「プロになるためのWeb技術入門」書籍内容まとめ Part2

# 「プロになるためのWeb技術入門」書籍内容まとめ Part2
この記事では、書籍で紹介されている内容やキーワードなどをまとめたものとなります。
そしてこの記事はPart2ということで前回記事の続きとなります。

前回の記事はこちら

https://qiita.com/furu_39/items/542ec3209ffa837981bc


## 目次
- [4.CGIからWebアプリケーションへ](#4cgiからwebアプリケーションへ)
  - [4-5.ログイン状態をどのようにして記憶するのか](#4-5ログイン状態をどのようにして記憶するのか)
  - [4-6.安全に状態を保存するための技術](#4-6安全に状態を保存するための技術)
  - [4-7.ピザ・ペントミノの完成](#4-7ピザペントミノの完成)
- [5.Webアプリケーションの構成要素](#5webアプリケーションの構成要素)
  - [5-1.WebサーバとWebクライアントの時代](#5-1webサーバとwebクライアントの時代)
  - [5-2.データベースサーバの登場](#5-2データベースサーバの登場)
  - [5-3.アプリケーションサーバの登場](#5-3アプリケーションサーバの登場)
  - [5-4.Webシステムの三層構成](#5-4webシステムの三層構成)
- [6.Webアプリケーションを効率よく開発する仕組み](#6webアプリケーションを効率よく開発する仕組み)
  - [6-3.Webアプリケーションのアーキテクチャ](#6-3webアプリケーションのアーキテクチャ)
  - [6-4.フレームワークによるアーキテクチャの実現](#6-4フレームワークによるアーキテクチャの実現)
  - [6-5.レイヤパターンによるデータアクセス層の分離](#6-5レイヤパターンによるデータアクセス層の分離)
  - [6-6.O/Rマッピングフレームワークによるデータアクセス層の実現](#6-6orマッピングフレームワークによるデータアクセス層の実現)
  - [6-7.フレームワーク利用におけるメリットとデメリット](#6-7フレームワーク利用におけるメリットとデメリット)
- [7.セキュリティを確保するための仕組み](#7セキュリティを確保するための仕組み)
  - [7-1.なぜセキュリティを確保しなければならないのか](#7-1なぜセキュリティを確保しなければならないのか)
  - [7-2.代表的なWebアプリケーションの攻撃手法とその対策](#7-2代表的なWebアプリケーションの攻撃手法とその対策)
  - [7-3.設計・実装ミスに起因する誤動作やセキュリティ問題を防ぐための対策](#7-3.設計・実装ミスに起因する誤動作やセキュリティ問題を防ぐための対策)

## CGIからWebアプリケーションへ
PHPは主にWebサーバー環境で動作するスクリプト言語で、サーバーに対してクライアント（ブラウザなど）からリクエストが送られた際に、そのリクエストに応じてPHPスクリプトが実行される仕組みです。ここでは、PHPがどのように実行されるのか、そしてCGIとモジュール（例えばApacheのmod_php）の違いについて説明します。

### PHPの実行方法
1.PHPエンジンとは？
- PHPエンジンは、PHPコードを解析し、実行するプログラムです。通常、PHPエンジンはWebサーバー（例：ApacheやNginx）と連携して動作します。
- PHPスクリプト（例：login.php）がリクエストされると、WebサーバーはPHPエンジンにこのリクエストを渡し、PHPエンジンがそのスクリプトを解釈・実行し、結果をサーバーに返します。

2.リクエストの流れ
- クライアント（ブラウザなど）がlogin.phpに対してGETリクエストを行うと、Webサーバー（例えばApache）はそのリクエストを受け取ります。
- Webサーバーは、リクエストされたファイルの拡張子（.php）を確認し、その拡張子がPHPスクリプトであることを認識します。
- WebサーバーはPHPエンジンを呼び出して、login.phpスクリプトを実行します。その結果として生成されたHTMLやその他のコンテンツをクライアントに返します。

### CGIとモジュールの違い
1.CGI（Common Gateway Interface）
- 仕組み: CGIはWebサーバーとアプリケーションの間のインターフェースで、サーバーがリクエストを受け取るたびに、新しいプロセスとしてPHPを起動します。
- 動作: サーバーがPHPスクリプトを実行するために、毎回新しいPHPプロセスを立ち上げ、スクリプトを実行します。リクエストごとに新しいプロセスが生成されるため、オーバーヘッドが大きくなります。
- 長所: サーバーの設定が単純で、セキュリティ的に分離された環境でスクリプトを実行できる。
- 短所: リクエストごとに新しいプロセスを立ち上げるため、性能が低くなりがちで、特にトラフィックが多い場合に非効率。

2.モジュール（例：Apacheのmod_php）
- 仕組み: PHPをApacheのモジュールとして組み込む方法。mod_phpはApacheのプロセスの一部として動作し、PHPの実行環境が常にメモリに常駐しています。
- 動作: ApacheはPHPスクリプトのリクエストを受け取ると、モジュール（mod_php）を介してそのままスクリプトを実行します。CGIとは異なり、新しいプロセスを起動する必要がなく、同じプロセス内でPHPが実行されます。
- 長所: プロセスのオーバーヘッドがなく、パフォーマンスが良い。メモリ消費が抑えられ、リソースの効率的な利用が可能。
- 短所: WebサーバーとPHPが密に連携しているため、セキュリティの面で注意が必要で、WebサーバーのクラッシュがPHPモジュールに影響を与えることがあります。

### PHPエンジンとWebサーバーの連携
- Apacheの場合:
    - Apacheはmod_phpを使ってPHPを処理します。mod_phpはApacheに組み込まれており、PHPスクリプトがリクエストされると、このモジュールがPHPコードを解釈し、実行結果を返します。
    - これは、CGIよりも効率的で、特に高トラフィックな環境ではパフォーマンスの向上につながります。

### 4-5.ログイン状態をどのようにして記憶するのか
#### ステートフルなプロトコルとステートレスなプロトコル
「**Stateful Protocol（ステートフル・プロトコル）**」...FTPなど、リクエストに伴って状態が変わっていく、状態を保つプロトコル。
「**Stateless Protocol（ステートレス・プロトコル）**」...HTTPなど、状態を持たないプロトコル。

WWWが考案された際に、FTPのようなプロトコルが既にありましたがHTTPを考案しました。
理由としては、FTPは通信手順が多いため、オーバーヘッドが大きいこと。もう1つは、アクセスのためには認証を必要とすること。そこで、認証が不要でオーバーヘッドも少ない通信手順が簡単なステートレスなプロトコルとして、HTTPが新たに設計されたのです。

#### Cookieを利用して状態を保持する
HTTPはステートレスなプロトコルであり、ログイン状態などの情報をリクエスト間で保持することができません。そこで利用されるのが「**Cookie（クッキー）**」です。

**Cookieの役割**
Cookieは、WebサーバーとWebブラウザ間で小さな情報を交換し、Webブラウザに状態を持たせる技術です。CookieはHTTPの仕様を拡張したもので、サーバー側から送られた情報をクライアント側に保持し、次回のリクエスト時にその情報を送り返すことで、ユーザーの状態を識別できます。

**Cookieの仕組み**
1. Cookieの送信: WebサーバーがHTTPレスポンスのヘッダに「名前=値」の形式で情報を付加し、これをCookieとしてWebブラウザに送信します。
2. Cookieの保持と送信: Webブラウザは受け取ったCookieを保存し、次回に同じサーバーへアクセスする際、保存したCookieをHTTPリクエストのヘッダに付けて送信します。
3. サーバー側の処理: Webサーバーはリクエストに含まれるCookieを確認し、ユーザーの状態（例えばログイン状態）を把握します。

**セキュリティ上の仕組み**
Cookieは特定のサーバーから送られたものだけが送信されるため、他のWebサーバーに対しては送られません。これにより、意図しない情報の漏洩を防ぐことができます。

Cookieはこのようなシンプルな仕組みで、Webアプリケーションの状態を管理する手段として広く使われています。


#### Cookie利用の実際を確認する
以下は、PHPを使った簡易的なログインシステムの例です。この例では、ユーザー名とパスワードの正しさをチェックし、ログインに成功した場合にCookieを使って状態を保持します。

**簡易的なログインシステムの例**
ステップ 1: ログインフォーム (login.html)
まず、ユーザーがログイン情報を入力するフォームを作成します。
```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Login</title>
</head>
<body>
    <form action="login.php" method="post">
        <label for="username">Username:</label>
        <input type="text" name="username" id="username" required>
        <br>
        <label for="password">Password:</label>
        <input type="password" name="password" id="password" required>
        <br>
        <input type="submit" value="Login">
    </form>
</body>
</html>
```

ステップ 2: ログイン処理 (login.php)
次に、ユーザーの入力情報をチェックし、正しければCookieを設定します
```php
<?php
// 簡易的なユーザー情報（通常はデータベースから取得）
$valid_username = "admin";
$valid_password = "password123";

// フォームから送信されたデータを取得
$username = $_POST['username'];
$password = $_POST['password'];

// 入力されたユーザー名とパスワードが正しいか確認
if ($username === $valid_username && $password === $valid_password) {
    // 正しい場合、Cookieを設定（1時間有効）
    setcookie("loggedin", "true", time() + 3600);
    echo "Login successful! Welcome, " . htmlspecialchars($username) . ".";
    echo "<br><a href='protected.php'>Go to protected page</a>";
} else {
    // 誤っている場合、エラーメッセージを表示
    echo "Invalid username or password.";
}
?>
```

ステップ 3: 保護されたページ (protected.php)
最後に、ログイン状態が維持されているかを確認するページを作成します。
```php
<?php
// Cookieが設定されているかチェック
if (isset($_COOKIE["loggedin"]) && $_COOKIE["loggedin"] === "true") {
    echo "Welcome to the protected page!";
} else {
    // ログインしていない場合、アクセスを拒否
    echo "Access denied. Please log in first.";
    echo "<br><a href='login.html'>Login here</a>";
}
?>
```
**このログインシステムの動作説明**
- ログインフォーム (login.html):
ユーザーは、フォームにユーザー名とパスワードを入力し、login.phpにPOSTリクエストを送信します。

- ログイン処理 (login.php):
login.phpは、送信されたユーザー名とパスワードを検証します。
正しければ、setcookie()関数でloggedinという名前のCookieを設定し、ユーザーに「ログイン成功」のメッセージを表示します。
間違っていれば、「ユーザー名またはパスワードが無効です」と表示します。
- 保護されたページ (protected.php):
このページは、$_COOKIE変数を使ってユーザーのログイン状態をチェックします。Cookieが存在し、かつ「true」の場合のみ、アクセスを許可します。それ以外の場合は、「アクセス拒否」と表示します。

**Cookieの取消処理**
Cookieの取り消し（削除）を行うには、setcookie()関数を使用して、同じCookie名で有効期限を過去の日付に設定します。これにより、ブラウザはそのCookieを無効とし、削除します。

ステップ 4: ログアウト処理 (logout.php)
ログアウト時にCookieを削除するためのコードを作成します。
```php
<?php
// Cookieを削除するために有効期限を過去に設定
setcookie("loggedin", "", time() - 3600);

// ログアウトメッセージを表示
echo "You have been logged out.";
echo "<br><a href='login.html'>Login again</a>";
?>
```
**このコードの動作説明**
setcookie("loggedin", "", time() - 3600);:

setcookie()関数で「loggedin」という名前のCookieを再度設定していますが、time() - 3600のように、過去の時間（ここでは1時間前）を指定します。これにより、ブラウザはそのCookieを削除するように指示されます。
値として空の文字列（""）を指定することで、Cookieの内容もクリアされます。
ログアウトメッセージの表示:

Cookieの削除が成功した後、ユーザーに「ログアウトしました」というメッセージを表示し、再度ログインを促します。

#### Cookieの`expires`属性について

`expires`は、HTTP Cookieの有効期限を指定するための属性で、Cookieの保存期間を制御します。この属性を設定することで、Cookieがいつまで有効か（いつブラウザによって削除されるべきか）を指定できます。`expires`属性がない場合、Cookieは「セッションクッキー」として扱われ、ブラウザが閉じられるまで保持されます。

#### `expires`の使い方

- `expires`属性には、Cookieが有効である期限を、UTC（協定世界時）での日時の形式で指定します。
- 例えば、次のように設定します:  
  `Wed, 21 Oct 2024 07:28:00 GMT`

これにより、指定された日時を過ぎると、ブラウザはそのCookieを削除します。

#### `expires`の例

PHPでCookieを設定するときに、`expires`を設定する方法の例を示します。

```php
<?php
// 1時間後に期限が切れるCookieを設定
setcookie("user", "John", time() + 3600); // time() + 3600 は現在の時間から1時間後
?>
```

**上記コードの説明**
- setcookie("user", "John", time() + 3600);
    - setcookie関数の3つ目の引数で、time() + 3600としています。
    - time()は現在のUNIXタイムスタンプを返す関数で、3600は1時間（60秒 × 60分）を表します。これにより、現在の時刻から1時間後を有効期限として設定しています。

**expiresとmax-ageの違い**
- expires: 有効期限を「特定の日時」で指定するもの。古いブラウザとの互換性のために使われることが多い。
- max-age: Cookieの有効期限を「現在からの秒数」で指定するもの。より正確に有効期限を設定できる。
    - 例: max-age=3600とすると、現在から3600秒（1時間）後にCookieの有効期限が切れます。

**expiresの注意点**
1. ブラウザの時間に依存: expiresはブラウザの時計に依存するため、クライアントの時間設定が正しくない場合、意図したとおりに動作しない可能性があります。
2. 互換性の問題: 一部の古いブラウザではmax-ageがサポートされていないため、互換性を考慮してexpiresを使用することがあります。
3. 時間形式の指定: expiresの時間形式は、UTCの日時を"英語の曜日と月の名前"で指定する必要があるため、誤った形式で指定すると正しく動作しません。


### 4-6.安全に状態を保存するための技術
#### Cookieにまつわる問題点
Cookieにはセキュリティ上の問題点があり、それを理解することが重要です。
Cookieを利用した情報のやり取りはHTTPのリクエストヘッダやレスポンスヘッダを利用して行われます。
PC上に保存されたCookieも簡単に覗くことができてしまい、特にユーザー名やパスワード、クレジットカード番号といった情報などが漏れてしまうとなりすまし等のセキュリティリスクがあります。

個人情報や金銭に関わる情報をCookie上にそのまま登録することは絶対に行ってはいけません。
そこで、より安全に多くの情報を保持するための方法として考え出されたのが「**セッション（Session）**」と呼ばれる仕組みです。


#### コラム　Cookieはどこに保存されている？
Cookieは、ユーザーのブラウザに保存される小さなデータです。具体的には、各ブラウザ（例えば、Google Chrome、Mozilla Firefox、Safariなど）は、Cookieを専用のファイルやデータベースに保存しています。

**保存の仕組み**
1.ブラウザ内の保存場所:

- ブラウザは、Cookieを各ドメインごとに保存します。たとえば、example.comから送信されたCookieは、そのドメインに関連するCookieストレージに格納されます。通常、これはブラウザのキャッシュディレクトリやプロファイルフォルダ内にあるファイルやデータベースに保存されます。

2.ローカルのデバイス上:

- Cookieはユーザーのデバイス上に保存されており、ブラウザを通してWebサーバーとデータをやり取りする際に使用されます。例えば、パスワードの自動入力や、ショッピングカートの内容の保存、広告ターゲティングなどの機能を提供するために利用されます。

**Cookieの種類による保存方法の違い**
- セッションクッキー:
    - ブラウザのメモリに一時的に保存され、ブラウザを閉じると削除されます。これらはユーザーのデバイスに長期間保存されることはありません。
- パーシステントクッキー（永続的クッキー）:
    - 指定された有効期限までブラウザに保存されます。expiresまたはmax-age属性で設定され、例えば、数日や数週間、数か月などの有効期間を持ちます。

**注意点**
- Cookieは同一オリジンポリシー（同じドメイン）に従って保存・使用されるため、他のドメインからはアクセスできません。これにより、プライバシーとセキュリティが保護されます。
- 一部のCookieは「セキュア」属性を持つことができ、これはHTTPS通信の場合にのみ送信されることを意味します。また、「HttpOnly」属性が付与されると、JavaScriptからアクセスできないように設定できます。

Cookieの保存場所とその制御の仕組みを理解することで、Webアプリケーションの設計やセキュリティ対策に役立てることができます。

:::note info
### Cookieの挙動: タブ、ウィンドウ、シークレットモード、異なるアカウントやデバイスでの動作

Cookieの動作は、タブやウィンドウ、シークレットウィンドウ、異なるGoogleアカウント、異なるデバイス（スマホやPC）にアクセスする場合によって異なります。それぞれのケースでCookieの動作を以下に説明します。

### 1. 同一タブとウィンドウ
- **動作**:  
  同一タブまたはウィンドウ内でのアクセスでは、Cookieは通常通り共有されます。たとえば、同じドメインのページ間で移動する際に、保存されたCookie情報（例：ログイン状態）はそのまま維持されます。
- **理由**:  
  Cookieはブラウザ内でドメイン単位で管理されているため、同一ドメインでのアクセスでは、どのタブやウィンドウからのアクセスでも同じCookieが利用されます。

#### 2. 異なるタブとウィンドウ
- **動作**:  
  異なるタブやウィンドウであっても、同じブラウザを使っている限り、同じドメインにアクセスする場合は同じCookieが共有されます。
- **理由**:  
  Cookieはブラウザのメモリやローカルストレージに保存され、同一ドメインでアクセスする限り、全てのタブとウィンドウで共通に利用されます。

#### 3. シークレットウィンドウ（プライベートブラウジング）
- **動作**:  
  シークレットウィンドウでは、通常のウィンドウとは別のCookieが一時的に使用されます。シークレットモードを終了すると、そのセッションで利用されていたすべてのCookieは自動的に削除されます。
- **理由**:  
  シークレットモードはユーザーのプライバシーを保護するために設計されており、Cookieやキャッシュ、履歴などのデータをそのセッション中だけ一時的に保存します。ブラウザを閉じた時点でこれらのデータは削除されます。

#### 4. 別のGoogleアカウント（同じブラウザ）
- **動作**:  
  異なるGoogleアカウントであっても、同じブラウザ上でのアクセスであれば、同一ドメインにアクセスする場合は共通のCookieが利用されます。ただし、Googleサービスを利用する場合などでは、アカウントごとに異なるセッションが保持されるため、アクセス内容が変わる場合があります。
- **理由**:  
  Cookieはドメイン単位で管理されるため、ブラウザ上の異なるGoogleアカウントの切り替えだけでは、一般的なWebサイトのCookieの動作には影響しません。ただし、Googleが提供するサービス（例：Gmail、Google Driveなど）では、アカウント情報をセッションCookieで管理しており、そのアカウントのセッションが切り替わります。

#### 5. スマホとPC（異なるデバイス）
- **動作**:  
  異なるデバイス（スマホとPC）間では、Cookieは共有されません。各デバイスのブラウザで独立してCookieが管理されます。
- **理由**:  
  Cookieはデバイスごとのブラウザで管理されているため、PCでのCookie情報はスマホには伝わりません。デバイス間でCookieを共有するためには、サーバーサイドのセッション管理（例：ログイン情報の保持）が必要です。

#### 6. 異なるブラウザ（同じデバイス）
- **動作**:  
  同じデバイスでも異なるブラウザ（例：ChromeとFirefox）を使用している場合、Cookieは共有されません。
- **理由**:  
  Cookieはブラウザごとに個別に管理されるため、ブラウザ間でCookieが共有されることはありません。

#### まとめ
- **同一タブ/ウィンドウ**: 同じCookieが共有される。
- **異なるタブ/ウィンドウ**: 同じCookieが共有される。
- **シークレットウィンドウ**: 別のCookieが一時的に使用され、終了時に削除される。
- **別のGoogleアカウント**: 一般的なCookieは影響しないが、Googleサービス内では異なるセッションが使用される。
- **異なるデバイス**: Cookieは共有されない。
- **異なるブラウザ**: Cookieは共有されない。

Cookieの保存場所と共有範囲について理解することで、セキュリティやプライバシーの保護、アプリケーションの設計をより効果的に行うことができます。

:::

#### セッションで処理の進行状況を管理する
セッションとは、ユーザーとサーバー間で行われる一連のやり取り（処理）の流れを管理する仕組みです。セッションを利用することで、ユーザーの操作状況や進行中のプロセスをサーバー側で一時的に記録し、複数のHTTPリクエスト間で情報を引き継ぐことができます。

例えば、次のようなWebアプリケーションでの流れがセッションにあたります：

1. ユーザーがログインする
2. 注文するピザを選択する
3. 注文を確認する
4. ログアウトする

このように、Webアプリケーションで複数回のHTTPリクエストを行いながら、一連の操作を行う必要がある場合、その処理の流れ全体をセッションと呼びます。セッションによって、ユーザーがアプリケーション内で行う操作の連続性が維持されます。


#### セッションの状態をどこで保持するか
セッションの状態を保持するためには、ユーザーがWebアプリケーションで行った操作を記憶する必要があります。これにはいくつかの方法がありますが、最も一般的なのは**Cookie**を利用する方法です。しかし、Cookieには以下の制限やリスクがあります：

- Cookieは保持できる情報量に制限がある。
- Cookieに保存された情報は、第三者に漏洩するリスクがある。

そのため、セッションの状態を管理するためには、Cookieに依存しない方法が望まれます。

**セッションID（SessionID）の利用**
代わりに、セッション管理のために「受付番号」のような一意でプライバシーに関係しないデータを使います。このデータを**セッションID（SessionID）**と呼びます。セッションIDを用いることで、Cookieの問題を回避しながらセッションの状態を保持できます。

**セッションIDの役割**
- セッションIDは、ユーザーを一意に識別するための番号であり、その番号自体には意味はありません。
- 重要なのは、WebサーバがセッションIDを使って、どのユーザーがリクエストを送信したのかを特定できることです。

**セッションデータの保持方法**
- セッションの状態は、Webサーバ側で保持されます。たとえば、コンピュータのメモリやデータベースを使用してユーザーの注文状況や進行状況を管理します。
- ユーザーのブラウザ（クライアント）とWebサーバ間では、セッションIDだけがやり取りされます。セッションIDはユーザーのブラウザに保存され、次回のリクエスト時にサーバに送信されます。

#### HTTPにおけるセッションIDの受け渡し方法
Webアプリケーション側でログインなどの操作を行いセッションを開始する際、Webサーバ側が新しい**セッションID**を発行します。このセッションIDは、HTTPレスポンスの**Cookie**に格納され、クライアント（ユーザーのブラウザ）へ渡されます。

#### セッションIDの受け渡しの流れ
1. **セッション開始時**  
   ユーザーがWebアプリケーションにログインするなど、セッションを開始するアクションを行うと、Webサーバは新しいセッションIDを生成します。

2. **セッションIDの送信**  
   発行したセッションIDは、HTTPレスポンスのCookieに格納され、クライアント（ユーザーのブラウザ）に送信されます。

3. **以降のリクエスト**  
   クライアントは、以降のHTTPリクエスト時に、受け取ったCookie（セッションIDが含まれる）をサーバに送信します。

4. **サーバ側の処理**  
   WebサーバはCookie内のセッションIDを使用して、サーバ側のメモリやデータベースに保存されているクライアントの状態（ログイン状態、ショッピングカートの中身など）を復元します。

#### セッションIDの利用メリット

結局のところ、Cookieを使って情報をやり取りしますが、重要な違いは**Cookieに情報そのものを格納するのか、セッションIDだけを格納するのか**という点です。

- **情報そのものをCookieに格納する場合**：Cookieの情報量には制限があり、また第三者に漏洩するリスクがあります。
- **セッションIDだけをCookieに格納する場合**：Cookieに格納する情報量の制限を気にせず、またサーバ側でデータを管理するため、より高い安全性を確保できます。

セッションIDの使用により、クライアントとサーバ間での情報のやり取りが安全で効率的になります。

#### セッションID利用の実際を確認する
**PHPSESSID**
セッションIDは、PHPなどのサーバーサイド言語を用いて、ユーザーごとに一意の識別子として生成されます。PHPの場合、デフォルトのセッションIDは「**PHPSESSID**」という名前でCookieに保存されます。

この「PHPSESSID」にはセッションを識別するための値が格納され、サーバーとクライアント間でやり取りされます。

#### セッションIDによるユーザの識別
セッションIDを使用することで、Webアプリケーションは個々のユーザーを識別し、それぞれの操作を追跡・管理することができます。たとえば、ユーザーが異なるログインIDでログインすると、新しいセッションIDが生成され、サーバー側で別のセッションとして扱われます。

- **別のログインIDでログイン**  
  別のログインIDを使用して再度ログインした場合、サーバーは新しいセッションIDを発行し、異なるユーザーセッションとして識別・管理します。これにより、異なるユーザー間のセッションが混同されることを防ぎます。

セッションIDの利用により、ユーザーの識別とセッション管理が確実かつ安全に行われます。


### 4-7.ピザ・ペントミノの完成
セッションには自由に情報を格納できるため、この特性を利用してショッピングカートの機能を実現することができます。たとえば、ユーザーが「ピザ」を注文して別のページに遷移したり、後から追加で注文を行ったりする場合、セッションを利用することでこれを管理します。

具体的には、ユーザーの注文内容（品名や注文数）をサーバ側で記憶し、セッションIDをキーとして保持します。クライアント側では、Cookieに保存されたセッションIDをサーバに送り返すことで、サーバは対応するセッションデータを参照し、ショッピングカートの状態を管理します。

#### コラム　Webサーバによる認証機能 ?Basic認証?
**Basic認証**（ベーシック認証）は、HTTPの仕様の一部として定められた最もシンプルな認証方式です。この認証機能はWebサーバ自体によって提供されており、フォーム認証のようにプログラムを記述する必要がなく、サーバの設定だけで実現できます。

Basic認証の仕組みでは、特定のディレクトリ配下のURLにアクセスする際に、ユーザー名とパスワードの入力を求められます。しかし、これはあくまで簡易的な認証方法であり、以下の制限があります。

- セッションとの連携ができない。
- パスワードが平文（暗号化されていない状態）で送信されるため、セキュリティリスクがある。

そのため、Basic認証を使用する際は、SSLによる暗号化通信と組み合わせることで安全性を向上させることが推奨されます。また、より安全な方法として、パスワードを直接送信せずに認証する**Digest認証**を使用する方法もあります。


## 5.Webアプリケーションの構成要素
WebアプリケーションはクライアントとサーバがHTTPによって通信することで実現されています。そのサーバは、実際のシステムでは物理的に1台とは限らず、システム規模や特性にあわせて変化します。
しかし、論理的にはWebサーバとアプリケーションサーバ、データベースサーバの3種類しかありません。Webアプリケーションシステムを理解するには、これらの役割を理解することが重要です。

### なぜWebアプリケーションの構成を理解しなければならないのか
現実のシステムでは、多くの場合サーバ側で複数のコンピュータが連携して動作しています。
さらに、これらのサーバ側のコンピュータは、システムの規模や用途に応じてどのように役割分担するか、何台で分担するか、といった構成が違います。
具体的に言うと、小規模なシステムでは1台のコンピュータでWebシステムを実現しているものもあります。
中規模なものでは3台前後、大規模なものになると数10台から数100台にまで膨れます。

Webシステムを開発する立場の人は、サーバサイドのコンピュータがどのように役割分担して動作しているのかを理解しておく必要があります。ソフトウェアを作る上でも役割分担を意識する必要がありますし、いざシステムが動かなくなった時に、どこに原因があるのか突き止めることができないからです。

### 5-1.WebサーバとWebクライアントの時代
#### WWWの黎明期
WWWの初期には、静的なHTMLページが主流でした。これにより、ユーザーは事前に作成されたページを表示することができました。

#### CGIの時代
CGI（Common Gateway Interface）の登場により、動的なコンテンツの生成が可能になり、Webの機能が大幅に拡張されました。CGIを利用することで、サーバーサイドでプログラムを実行し、ユーザーのリクエストに応じて動的なページを生成することができるようになりました。

### 5-2.データベースサーバの登場
#### 大量の情報をどのようにして管理するか
情報量が増大する中で、効率的にデータを管理する必要がありました。これには、データの整理、検索、更新、削除などの機能を提供する仕組みが必要です。

#### データベース管理システムの登場
DBMS（データベース管理システム）は、データを管理し、ユーザーがデータにアクセスできるようにするソフトウェアです。これにより、大量のデータを効率的に管理し、必要な情報を迅速に取得できるようになりました。

#### コラム　DB? 　DBMS?　RDBMS?
- **DB（データベース）**: データを整理して保存するためのシステムです。
- **DBMS（データベース管理システム）**: データベースを管理し、データの操作をサポートするソフトウェアです。
- **RDBMS（リレーショナルデータベース管理システム）**: データをテーブル形式で管理し、データ同士の関係をサポートするDBMSです。

#### データベースに対する操作
- **CRUD**: データベースでの基本的な操作。Create（作成）、Read（読み取り）、Update（更新）、Delete（削除）。
- **テーブル**: データを行と列で構成する基本的な構造。
- **カラム**: テーブルの各列で、特定のデータ属性を表します。
- **レコード**: テーブルの各行で、個々のデータ項目を表します。

#### コラム　データベース設計はITシステムの要
データベース設計は、システム全体の効率性や性能に大きく影響します。適切な設計が行われることで、データの整合性や操作の効率が大幅に改善されます。

#### データベースから情報を抽出する
SQL（Structured Query Language）クエリを使って、データベースから必要な情報を抽出します。SQLを用いることで、特定の条件に基づいてデータを取得することができます。

#### 必要な情報をSQLでデータベースへ伝える
SQLを使って、データベースに情報を登録し、更新します。SQLクエリは、データベースに対して「何を」「どこから」「どのように」操作するかを指示します。

#### データベースとクライアントの関係
データベースは独立して動作するプロセスです。クライアントアプリケーションがデータベースに対してSQLクエリを渡し、情報の抽出や更新を依頼します。クライアントとデータベースのやり取りは、以下の2つの主要な方法で行われます。
- **データベースとクライアント**: クライアントは直接データベースにクエリを送信し、結果を受け取ります。
- **アプリケーションプログラム**: アプリケーションがデータベースに対してSQLクエリを生成し、実行結果をユーザーに提供します。

#### データベースサーバの分離
データベースをWebサーバ上で動作する場合、データベース用に新しいコンピュータを用意する必要はありません。
既にあるWebサーバへデータベースをインストールするだけで済みます。実際、利用者の少ない小規模なWebアプリケーションシステムはこの構成になることも多いです。
ただし、この構成ではデータベースが大きくなった時にディスクの領域を圧迫したり、多くの利用者がアクセスしてCPUの負荷が高くなったりした場合、システムがダウンしてしまう危険性があります。

そこで、一般的にはWebサーバを動作させるコンピュータとデータベースを動作させるコンピュータを別々に用意し、各プロセスをそれぞれのコンピュータ上で動かすようにします。
そうすることで、各コンピュータの仕事が分散されて負荷が下がると言うメリットがあります。また、DBサーバだけを利用したい他のクライアントが存在する場合に好都合です。

#### Webアプリケーションとデータベースの通信
Webアプリケーションとデータベースの通信方法
ここで使用されるプロトコルはHTTPのように標準化されているのではなく、データベース製品固有の通信プロトコルを使って通信しています。
DBアクセス用のライブラリが動作していて、アプリケーション開発者がこのプロトコルを意識する必要はありません。ただ、SQL発行の裏側はこんな仕組みになっている、と言うことだけは押させておいてください。

:::note info
### Webアプリケーションとデータベースの具体的な通信方法

#### 1. クライアントからのリクエスト
- **ユーザーのアクション**: ユーザーがWebアプリケーションでデータベースにアクセスするアクションを実行します（例: 商品を検索する、注文を行う）。
- **アプリケーションの処理**: Webアプリケーションがこのアクションに対応するSQLクエリを生成します。例えば、商品の詳細情報を取得するためのクエリを作成します。

#### 2. データベースアクセスライブラリ
- **SQLクエリの送信**: アプリケーションはデータベースアクセス用のライブラリ（例: PDO、JDBC、ORM）を使って、生成したSQLクエリをデータベースサーバーに送信します。
- **プロトコル**: ライブラリはデータベース製品特有の通信プロトコルを使用します。例えば、MySQLでは「MySQLプロトコル」、PostgreSQLでは「PostgreSQLプロトコル」を使用します。

#### 3. データベースサーバーとの通信
- **通信プロトコル**: データベースサーバーは、クライアントから送信されたSQLクエリを受け取るためのプロトコルを持っています。このプロトコルはデータベース製品に特有で、クエリの解析や処理を行います。
  - **MySQL**: 「MySQLプロトコル」を使用。リクエストをバイナリ形式で送信し、結果をバイナリ形式で受け取る。
  - **PostgreSQL**: 「PostgreSQLプロトコル」を使用。テキストまたはバイナリ形式でクエリを送信し、レスポンスもテキストまたはバイナリ形式で受け取る。

#### 4. データベースサーバーの処理
- **クエリの実行**: データベースサーバーは受け取ったSQLクエリを解析し、要求されたデータを取得・操作します。
- **結果の生成**: クエリの結果を生成し、クライアントに返す形式に変換します。

#### 5. レスポンスの受信と処理
- **アプリケーションの受信**: Webアプリケーションはデータベースサーバーからのレスポンスを受け取り、結果を適切な形式に変換してユーザーに表示します。
- **エラーハンドリング**: エラーが発生した場合、エラーメッセージを処理し、ユーザーに適切な情報を提供します。

#### 例: MySQLの通信プロセス
1. **アプリケーション**: `SELECT * FROM products WHERE id = 1;`
2. **データベースアクセスライブラリ**: SQLクエリをMySQLプロトコルでMySQLサーバーに送信。
3. **MySQLサーバー**: クエリを解析してデータベースから情報を取得。
4. **MySQLサーバー**: 結果をバイナリ形式でアプリケーションに送信。
5. **アプリケーション**: 結果を受け取り、ユーザーに表示。
:::

#### コラム　代表的なデータベース製品
#### 1. Oracle Database
- **概要**: 大規模な商業アプリケーション向けに設計された商用データベースです。
- **特徴**: 高いパフォーマンス、スケーラビリティ、セキュリティを提供し、多くの企業で利用されています。

#### 2. Microsoft SQL Server
- **概要**: Microsoftが提供する商用のリレーショナルデータベース管理システム（RDBMS）です。
- **特徴**: Windows環境との統合が強力で、ビジネスインテリジェンスやデータウェアハウジング機能も充実しています。

#### 3. PostgreSQL
- **概要**: オープンソースのリレーショナルデータベース管理システムです。
- **特徴**: 高い拡張性と柔軟性を持ち、SQL標準に準拠しつつも独自の機能を多く提供しています。

#### 4. MySQL
- **概要**: オープンソースのリレーショナルデータベースで、特にWebアプリケーションで広く使用されています。
- **特徴**: 軽量で高性能、豊富なサポートがあります。「GPL」と「商用ライセンス」の2つの形態があります。

### 5-3.アプリケーションサーバの登場
#### ServletやJSPはどこで動いているのか
ServletやJSPは、アプリケーションサーバ上で動作します。

#### Servlet / JSPを動かすためのアプリケーションサーバ
アプリケーションサーバは、ServletやJSPの実行環境を提供します。
Webサーバへリクエストが届くたびに、新しいプロセスが起動されては終了していくCGIとは異なり、アプリケーションサーバはデータベースサーバ同様に、常にプロセスが実行されていると言う点が大きく異なります。

#### Webサーバとアプリケーションサーバの連携
Javaアプリケーションの構成として、**Apache HTTP Server**と**Tomcat**の組み合わせがあります。この場合、Apacheが受け取ったHTTPリクエストを、**mod_jk**というモジュールを使ってTomcat（アプリケーションサーバ）に転送します。Tomcatは、リクエストをWebアプリケーションに渡して処理し、その結果を逆のルートでApacheに返し、最終的にApacheがWebブラウザにレスポンスを返します。

#### Webサーバとアプリケーションサーバの分担
- **Webサーバ**: 静的コンテンツ（HTML、画像、CSSなど）を提供。
- **アプリケーションサーバ**: 動的コンテンツ（データベースとのやり取り、ビジネスロジックの実行など）を処理。

#### Webサーバとアプリケーションサーバ連携のメリット
Webサーバでは1つ1つのリクエストに対する処理量は小さい代わりに、受け付けるHTTPリクエストの数が非常に多くなる傾向があります。現在のWebサイトでは1つのページを表示するだけでも、ページの内容を記述したHTMLファイルの他にCSSファイル、JavaScriptファイル、各種画像ファイルなど様々な性的コンテンツが必要です。
これらの静的コンテンツを構成するファイルは1回のHTTPリクエストにつき1個ずつしかダウンロードできないため、1つのWebページを表示するだけでも大量のHTTPリクエストが発行されてしまうのです。

Webサーバとアプリケーションサーバを異なるノードに配置すると、軽い処理で回数の多い静的コンテンツへのリクエストはWebサーバに、回数が少なく処理の重い動的コンテンツへのリクエストはアプリケーションサーバへと、リクエストを分担できる。

#### 複数のTomcatへの転送
ロードバランシングを利用することで、複数のTomcatサーバにリクエストを分散させ、負荷を均等にすることができます。

#### Webサーバの機能を持ったアプリケーションサーバ
一部のアプリケーションサーバ（例: Tomcat）は、Webサーバの機能も内蔵しており、単体でWebサーバとしても動作します。

#### コラム　アプリケーションサーバの提供する機能
アプリケーションサーバは、Webアプリケーションの実行に必要な多くの機能を提供し、複雑な業務処理を支えます。以下に、代表的な機能について説明します。

1. **セッション管理**
    - アプリケーションサーバは、ユーザーのセッション情報を管理します。セッションとは、ユーザーがWebアプリケーションを利用している間の一連のやり取りを指します。アプリケーションサーバは、セッション情報を管理することで、ユーザーが再度ログインすることなく連続して操作を行えるようにします。また、ユーザーごとの状態（カートの中身、ログイン状態など）を維持します。

2. **トランザクション管理**
    - トランザクション管理とは、一連のデータベース操作がすべて成功するか、またはすべて取り消される（ロールバック）ようにすることです。アプリケーションサーバは、データの一貫性と整合性を保つために、複数の操作を1つのトランザクションとしてまとめて管理します。例えば、ショッピングカートでの購入処理が途中で失敗した場合、すべての操作を元に戻すことでデータの不整合を防ぎます。

3. **データベース接続の管理**
    - SQL発行のためにデータベースへアクセスする際は、接続から切断までの手続きをきちんと実施する必要があり、切断処理を忘れてしまったりすると必要以上にメモリを消費してしまい、サーバダウンの原因にもなってしまいます。また、一般にデータベース接続処理は時間がかかることが多く、SQLを発行するたびに接続/切断を繰り返していると、システムのパフォーマンスが低下しています。
    - リソースプール（コネクション・プーリング）とは、データベース接続やスレッドなどのリソースを効率よく管理するための仕組みです。アプリケーションサーバは、これらのリソースをプールとして保持し、必要に応じて使い回すことで、システムのパフォーマンスを向上させます。これにより、新しいリソースを毎回生成するコストを削減し、同時に多くのリクエストを効率的に処理することができます。

4. **Webアプリケーションの管理とシステムの可用性・性能の向上**
    - アプリケーションサーバがダウンしてしまうと、システム全体が停止して業務に影響を与えてしまいます。このような問題を防ぐために、複数のアプリケーションサーバを用意しておき、ダウンしたサーバの処理を肩代わりするさせることでシステムの「可用性（Availability）」を向上させます。
そのためには、「セッション・レプリケーション（Session Replication）」といって、アプリケーションサーバ同士が連携してセッションの状態を共有する仕組みが必要になり、アプリケーションサーバにはこのような仕組みを提供しているものがあります。

### 5-4.Webシステムの三層構成
#### 最小構成のWebシステム
最小構成のWebシステムは、クライアント（Webブラウザ）、サーバ（Webサーバやアプリケーションサーバ）、データベースの3つのコンポーネントで構成されます。

#### 一般的な構成
クライアント（Webブラウザ）、Webサーバ、アプリケーションサーバ、データベースサーバ、それぞれのサーバを別々のノードに配置します。

#### Webシステムの三層構成
この三層構成により、システムの分離性、スケーラビリティ、保守性が向上します。

#### コラム　現代のWebシステムを支えるオープンソース
現代のWebシステムの多くは、オープンソースソフトウェア（OSS）によって支えられています。
OSSとは、「Open Source Software」の略で、ソースコードが公開され、誰でも自由に使用、変更、再配布できるソフトウェアのことです。OSSは、商用のソフトウェアと比べてコストが低く、技術的な柔軟性や透明性が高いため、多くの企業や開発者に支持されています。

代表的なOSSには、以下のようなものがあります。

1. **Linux**
   - Linuxは、オープンソースのオペレーティングシステム（OS）です。安定性やセキュリティの高さ、そしてカスタマイズの柔軟性から、WebサーバのOSとして広く利用されています。例えば、GoogleやFacebookといった巨大なWebサービスのインフラでもLinuxが使用されています。

2. **Apache HTTP Server**
   - Apacheは、世界で最も広く使われているオープンソースのWebサーバソフトウェアです。HTTPリクエストを処理し、静的なHTMLページや画像などのコンテンツを提供します。高い拡張性と豊富なモジュールを備えており、サーバの設定や機能を柔軟にカスタマイズできます。また、Apacheは大規模なWebサイトから小規模な個人サイトまで幅広く利用されています。

3. **Tomcat**
   - Apache Tomcatは、Java ServletやJavaServer Pages（JSP）を実行するためのアプリケーションサーバです。JavaベースのWebアプリケーションをホストするための標準的なプラットフォームとして、企業向けシステムのバックエンドで広く使用されています。Tomcatは、軽量で高速な動作が特長で、Java開発者にとって重要なツールです。

4. **MySQL**
   - MySQLは、オープンソースのリレーショナルデータベース管理システム（RDBMS）です。データの保存と検索、更新などを効率的に行うためのデータベースソフトウェアで、多くのWebアプリケーションで使用されています。MySQLは、柔軟で使いやすく、スケーラブルな設計を持ち、高トラフィックのWebサイトやアプリケーションでも高いパフォーマンスを発揮します。

5. **PostgreSQL**
   - PostgreSQLは、機能が豊富で拡張性が高いオープンソースのRDBMSです。高度なSQL準拠やACIDトランザクション、柔軟なデータ型をサポートしており、大規模なシステムでの利用にも適しています。PostgreSQLは、複雑なクエリやデータ分析が求められるアプリケーションにおいて優れたパフォーマンスを発揮します。

#### OSSのメリット

- **コスト削減**: オープンソースのライセンスは無料で、ソフトウェアの購入やライセンス更新にかかるコストが発生しません。
- **柔軟性とカスタマイズ性**: ソースコードにアクセスできるため、必要に応じてソフトウェアをカスタマイズし、特定のニーズに対応できます。
- **コミュニティサポート**: 世界中の開発者コミュニティからの貢献により、バグ修正や新機能の追加が迅速に行われます。
- **セキュリティの向上**: 多くの開発者がソースコードをレビューすることで、セキュリティの問題が早期に発見され、修正されることが多いです。

#### オープンソースソフトウェア（OSS）の役割

OSSは、企業や開発者にとって単なるコスト削減の手段ではなく、技術革新や開発速度の向上、透明性の確保をもたらします。これにより、多様なニーズに対応できる柔軟なシステムが構築可能です。OSSを活用することで、企業は自社のサービスに必要な独自機能を迅速に開発し、競争力を高めることができます。

現代のWebシステムの多くは、これらのOSSを組み合わせることで構築されており、その柔軟性、スケーラビリティ、コスト効率の高さが、インターネット上の多くのサービスを支えています。

#### コラム: オープンソースのライセンス

**オープンソースのライセンス**は、オープンソースソフトウェア（OSS）の利用や再配布、改変に関するルールを定めたものです。OSSは自由に使用できる反面、ライセンスによって守られており、利用者はそのルールに従う必要があります。

代表的なオープンソースのライセンスには以下のようなものがあります。

1. **GPL（GNU General Public License）**
   - GPLは、OSSのライセンスの中で最も厳格なものの一つです。ソフトウェアを改変して再配布する場合、元のソースコードと改変後のソースコードを公開し、同じGPLライセンスで配布する必要があります。これにより、OSSの自由な利用と改変が広く共有されることを目的としています。

2. **MITライセンス**
   - MITライセンスは、最もシンプルで自由度の高いライセンスの一つです。ソフトウェアを自由に使用、複製、変更、再配布することができ、商用利用も許されています。改変や再配布の際に、元の著作権表示とライセンスの文書を含める必要があるだけで、制限が非常に少ないのが特徴です。

3. **Apache License**
   - Apache Licenseは、商用利用を含めた幅広い利用を許可するライセンスです。MITライセンスと同様に自由度が高いですが、特許権の明示的な許諾も含まれています。ソフトウェアを再配布する際には、ライセンスの文書と著作権表示を保持する必要がありますが、改変後のソースコードを公開する義務はありません。

4. **BSDライセンス**
   - BSDライセンスも、MITライセンスに似たシンプルなライセンスで、ソフトウェアの自由な使用、改変、再配布を許可しています。制限が少なく、商用利用にも適しています。著作権表示とライセンスの文書を保持することが条件です。

## 6.Webアプリケーションを効率よく開発する仕組み
#### セッションスコープとリクエストスコープの違い
| | セッションスコープ | リクエストスコープ |
|:-:|:-:|:-:|
| 有効範囲  | セッションを開始してから終了するかタイムアウトするまで | リクエストを受けてからレスポンスを返すまで |
| 開始と終了 | Webアプリケーションが制御 | アプリケーションサーバが制御 |
| 主な使い方 | ユーザ情報の保持 | ページ遷移前後での情報保持 |

### 6-3.Webアプリケーションのアーキテクチャ
#### ロジックとデザインの分離
ロジックとデザインでは必要とされるスキルも異なるため、それぞれプログラマとデザイナが分業した方が品質も効率も上がります。アプリケーションを効率よく開発するためには、結果としてロジックとデザインの分離が必要ということなのです。

#### MVCモデルによるWebアプリケーションのアーキテクチャ
コンピュータ処理の基本的な流れは3つ。「入力（Input）」「処理（Process）」「出力（Output）」の3要素です。
一見複雑そうに見えるWebアプリケーション処理も、個々のリクエストに対する処理というレベルでは、単純にIPOの繰り返しに過ぎません。

このIPO + 画面遷移を整理すると、Webアプリケーションの取るべきアーキテクチャが見えてきます。
そしてこのアーキテクチャが「MVCモデル」です。

MVCモデルでは、アプリケーションを「モデル（Model）」「ビュー（View）」「コントローラー（Controller）」の3つの役割に分けて作ります。
- モデル（Model
    - モデルはアプリケーションの「処理」の部分とそれに関する情報の保持の役割を担当します。一方で画面に対する入出力といった部分に一切関わりを持ちません。
    - モデル担当の処理例
        - ログイン処理
        - 商品一覧をデータベースから取得する処理
        - ユーザーが選択した商品をショッピンカートに保存する処理
        - 商品の合計金額を計算する処理
- ビュー（View）
    -ビューはモデルによる処理結果の画面への表示を担当します。処理結果自体はモデルが持っていますから、ビューがモデルから処理結果を取り出して、ユーザーが見やすいように整形した上で画面へ表示します。
- コントローラー（Controller）
    - コントローラーは画面からの入力と、モデルの呼び出し及びその結果に従ったビューの呼び出しを担当します。コントローラーはユーザーが画面に入力した情報を取り出して、処理を担当するモデルに渡します。モデルの処理結果によって結果を表示するビューを選択して呼び出します。全体の流れを制御します。

#### MVCモデルによる処理の流れ
MVCモデルの処理の流れ
1. Wbeブラウザからリクエストを送信。
2. コントローラーが受け取り、リクエストからパラメータを取り出し、必要であればセッションからの情報の取り出しも行います。次にそれらの入力情報を処理するモデルを呼び出し、パラメータを渡します。
3. モデルで受け取ったパラメータを元にそれぞれの処理を行い、その結果をコントローラーへ返却します。
4. コントローラーはモデルから受け取った結果をもとに表示すべき画面を選択して、その画面を表示するためのビューを呼び出します。
5. ビューはモデルを参照して表示すべき情報を取り出します。
6. その結果をHTMLとして出力して、HTTPレスポンスとしてWebブラウザに返します。

### 6-4.フレームワークによるアーキテクチャの実現
#### フレームワークとは何か
Webアプリケーションは様々なものがありますが、アーキテクチャに大きな違いはありません。
その共通的なアーキテクチャの部分を半完成品のソフトウェアとして実現し、異なる部分だけを作り込めるようにしたのがフレームワークです。

### 6-5.レイヤパターンによるデータアクセス層の分離

#### レイヤパターンによるデータアクセス層の分離
- プレゼンテーション層
    - プレゼンテーション層は、システム利用者とのインターフェイスを担当するレイヤです。Webブラウザを通してユーザーからの入力を受け付けて下位レイヤであるビジネスロジック層へ渡し、その処理結果を再びWebブラウザへ表示させたり、画面遷移を制御したりといったことを相当するのがその役目です。
- ビジネスロジック層
    - ビジネスロジック層は、アプリケーションが実現すべき固有の処理を実行するためのレイヤです。ビジネスロジックは「業務ロジック」と訳されます。ビジネスロジックでは、ユーザーが入力した情報をプレゼンテーション層から受け取り、必要に応じてデータアクセス層を通じてデータベースを利用し、処理を実行します。処理結果は再びプレゼンテーション層へ返します。
- データアクセス層
    - データアクセス層は、ビジネスロジックとデータベースの仲立ちを行うためのレイヤです。データベースへアクセスするためには、多くのコードを記述しなければなりません。このような面倒な処理をビジネスロジックから切り離し、利用できるようにすることがデータアクセス層の役割となります。

#### DAOパターンによるデータアクセス層の実現
DAO（Data Access Object）パターンは、データベースとのやり取りを行うための「データアクセス層」を設計する方法です。このパターンを使用することで、データベースにアクセスするコードを一箇所に集約し、アプリケーションの他の部分から切り離すことができます。
通常、DOAはデータベースのテーブル毎に作成し、テーブルに対するCRUD処理をそれぞれメソッドとして実装するのが一般的です。

```
// 商品IDをキーとして商品を検索する
public ProductItem selectByItemId(String itemId);

// 引数で渡された商品情報を挿入する
public int insert(ProductItem productItem);

//引数で渡された商品情報を更新する
public int update(String itemId);

// 引数で渡された商品情報を削除する
public int delete(String itemId);
```

### 6-6.O/Rマッピングフレームワークによるデータアクセス層の実現
#### O/Rマッピングフレームワークの必要性
データベースへのアクセス処理をいかに簡単に実現するかは、Webアプリケーションシステム開発における大きな面倒の1つになっています。この問題を解決するために、現在では「O/Rマッピングフレームワーク」と呼ばれるフレームワークを利用することで、解決できるようになっています。

「O/Rマッピング」とは、どのような意味でしょうか。「O/R」とは、「Object/Relational」のことを指し、「O/Rマッピング」とは「プログラム言語のオブジェクトと、リレーショナルデータベースの対応を取る」という意味になります。

具体例として、ピザの注文を管理するとき、データベース上に下記のようなテーブル構造で管理をしています。
- 顧客テーブル
    - 顧客ID
    - 氏名
    - 電話番号
    - メールアドレス
- 商品テーブル
    - 商品ID
    - 商品名
    - 単価
- 注文テーブル
    - 注文ID
    - 顧客ID
    - 注文日時
- 注文詳細テーブル
    - 注文ID
    - 商品ID
    - 品数

```
注文票（サンプル）
注文日時：　　　　2010/1/16 17:05
氏名：　　　　　　山田　一郎様
電話番号：　　　　045-xxx-9012
メールアドレス：　yamada@xxx.yy.jp

| 品名        | 単価  | 注文数 | 金額      |
-----------------------------------------
|マルゲリータ   | ¥800 |   3   | ¥2,4700  |
|バジルトマト   | ¥900 |   3   | ¥2,700   |

```

注文票をWebブラウザ上に表示することを考えてみると、Javaのようなオブジェクト指向言語では、注文日時や氏名など、注文票ごとに持っている情報と「マルゲリータ」や「バジル・トマト」など、個々の注文品に関する情報を分けた方が、オブジェクトによる表現がしやすくなります。

```mermaid
classDiagram
    class 注文票 {
        +注文日時: String
        +氏名: String
        +電話番号: String
        +メールアドレス: String
        +合計注文数: Integer
        +合計注文金額: Integer
    }

    class 注文品 {
        +品名: String
        +単価: Integer
        +注文数: Integer
    }

    注文票 "1" --> "1..*" 注文品 : 持つ
```

このように表現方法には大きく違いがあり、リレーショナル・データベース上の表現と、オブジェクト指向言語におけるオブジェクトによる表現の違いを「インピーダンス・ミスマッチ」と呼んでいます。
この表現の違いを解決することが、「O/Rマッピングフレームワーク」の最大の役割となります。

#### RDBとオブジェクトのインピーダンス・ミスマッチ
O/Rマッピングフレームワークが登場する前は、JBDCを利用してデータベースを利用してデータベースから情報を取得し、それをオブジェクトに組み立て直すという単純なコードを大量に書かねばなりませんでした。
O/Rマッピングフレームワークを利用することで、開発作業自体を効率化することができるのです。

O/Rマッピングフレームワークは非常に便利ですが、データベースへどのようなSQLを発行するのかを細かく指定できないというデメリットもあります。
JBDCによるデータベースアクセスコードと比較すると簡単で、発行するSQLやテーブルの構成が変更になっても、ソースコードではなくマップファイルだけを変更すれば良いため、変更箇所が1箇所にまとまっていて変更に強いという利点もあります。

### 6-7.フレームワーク利用におけるメリットとデメリット
#### フレームワーク利用のメリット
1. 設計・品質工数の削減
2. 品質の向上
3. テスト工数の削減

- 設計・品質工数の削減
    - 最大のメリットとして、先人の優れた設計を再利用できること。
    - MVCモデルを採用することや、Javaのクラスレベルでどのように実現するかなどがフレームワークとして予め決められているので、利用者はフレームワークの規定に合わせて必要なコードを作成するだけで良いのです。
    - 共通的な部分は作成されているため、同じようなコードを新たに作成する必要はありません。O/Rマッピングフレームワークなど。

- 品質の向上
    - フレームワークを利用することで、新たに設計したりコードを書いたりする部分が大幅に削減できます。その結果、システム全体の品質向上にも寄与できるのです。
    - フレームワーク自身の品質という点でも、オープンソースとして開発・公開されており、世界中の開発者から利用されて常に不具合の修正や機能改善が行われています。そのため、歴史も長く、利用者も多く活発に開発・保守活動が行われているフレームワークほど品質面でも安心することができます。

- テスト工数の削減
    - 生産性と品質の向上はテスト工数の削減、システム全体の開発コストの削減にも寄与します。新たに開発した部分はテストが必ず必要になり、テスト自体がテスト計画の策定、テスト仕様書の作成、テストの実施といった非常に多くコストがかかります。フレームワークの利用によって作成するコードを減らすことができるため、テストも減らすことができます。
    - フレームワーク自身をテストする必要はないため、その分テストにかかる工数を減らすことができます。

#### フレームワーク利用のデメリット
1. 学習コストの最大
2. 設計における自由度の低下
3. 長期的な技術力の低下

- 学習コストの最大
    - 使い方の学習や利用するにあたっての学習コストがかかります。習熟して使いこなすことができるようにな流には、一定の時間がかかることを考慮に入れなければなりません。
    - 利用するフレームワークに合わせた設計手法やテスト手法も確立しなければなりません。
    - 先端フレームワークは品質が安定していなかったり、情報が少なく学習がしづらかったり、長期的な視線でどのフレームワークを利用すべきかについて考えなければなりません。

- 設計における自由度の低下
    - どんなフレームワークでも想定利用範囲が決まっており、利用者はフレームワーク設計者が意図した範囲内で利用することが想定されています。その想定を超えた範囲のことを実現すると、逆にフレームワークが足枷となって難易度が非常に高くなってしまうことが多くなります。
    - フレームワークを利用するということは、設計や機能に対する一定の自由度と引き換えに生産性や品質を向上させているのだということ意識しなければならないのです。

- 長期的な技術力の低下
    - フレームワークは簡単に利用できるように内部をブラックボックス化してしまうため、その裏側でどのようなことが行われているのかを知ることができなくなってしまいます。長期的にはフレームワークの裏に隠された様々な技術を習得する機会を奪ってしまうことにもなりかねません。


## 7.セキュリティを確保するための仕組み
Webアプリケーションに対する攻撃のパターンとしてどのようなものがあり、どのような対策を講じる必要があるのかを学ぶ必要があります。

### 7-1.なぜセキュリティを確保しなければならないのか
#### Webアプリケーションが守るべきセキュリティ
- 機密性
    - 第三者への情報の流出を防ぐこと
- 完全性
    - 第三者による情報の改ざんを防ぐこと
- 可用性
    - 適切な権限を持った人間が適切な情報を利用できること

### 7-2.代表的なWebアプリケーションの攻撃手法とその対策
#### SQLインジェクション
SQLインジェクションは、悪意のあるSQL文を実行させる攻撃手法です。
パラメータのバリデーション、エスケープやプリペアドステートメントを使って対策します。

#### クロスサイトスクリプティング（XSS）
XSSは、悪意のあるスクリプトを注入する攻撃です。HTMLの中に悪意のあるスクリプトを埋め込み実行する攻撃。
出力時にサニタイジング処理を行うことで対策します。PHPでは、htmlspecialcharsという関数を利用すると、引数に指定した文字列の中でHTMLの特殊文字を文字参照に置き換えてくれます。

#### セッションハイジャック
セッションハイジャックは、他人のセッションを乗っ取る攻撃です。以下の方法にて対策します。
1. クロスサイトスクリプティング
2. 通信経路の暗号化（SSL）
3. セッション・タイムアウトの値の変更
4. セッションIDのランダム化

#### クロスサイトリクエストフォージェリ
CSRFは、ユーザーが意図しない操作を強制する攻撃です。
ワンタイムトークンを使って対策します。


#### 強制ブラウズ
強制ブラウズは、認証されていないページに直接アクセスする攻撃です。
適切なアクセス制御を行うことで対策します。

#### ディレクトリトラバーサル
ディレクトリトラバーサルは、ファイルシステムの任意のファイルにアクセスする攻撃です。
サニタイジングやパスの検証を行うことで対策します。

### 7-3.設計・実装ミスに起因する誤動作やセキュリティ問題を防ぐための対策
#### 「戻る」ボタン対策
「戻る」ボタンによる問題、再注文などを防ぐための対策を行います。
1. ブラウザによるキャッシュの無効化
2. 戻るボタンの無効化
3. ワンタイムトークンの利用

#### ダブルサブミット対策
二重送信を防ぐための対策を行います。
- JavaScriptでの二重送信の対策処理を入れる
- ワンタイムトークンによる対策

#### hiddenタグに重要な情報を持たせない
hiddenタグに重要な情報を持たせないようにします。第三者が書き換え可能なため。
ワンタイムトークンによる対策

#### デバッグ情報を出力させない
デバッグ情報を本番環境で出力させないようにします。
ログファイルなど決められた場所へ出力するなど。

#### グローバル変数に情報を持たせない
グローバル変数に重要な情報を持たせないようにします。
誤って書き換えてしまったりするリスクが増えるため。