PHP - WEB - 12. セッションの詳細
引き続きセッションについて学習していきましょう。Webアプリケーションにおいてユーザとの一連のやりとりの間で発生するデータを保存するにはセッションという仕組みを使います。PHPにおいて、セッションを利用するためには予め session_start
関数を呼び出した後、 $_SESSION
変数にアクセスします。それでは、このときWebブラウザとWebサーバ間のHTTP通信ではどのようなデータのやりとりが行われているのでしょうか。ここでは具体的なHTTP通信のやりとりを中心に見ていくことにします。
Cookie
一般的にセッションはその内部でCookieという仕組みを使います。CookieとはHTTPのクライアント(Webブラウザ)上に少量のデータを保存する仕組みです。もともとHTTPの通信ではWebサーバからWebブラウザ上のコンピュータに対してファイルを作成したり、削除したりといった操作は禁止されています。これを許可してしまうとWebサーバから、Webブラウザを使っている利用者のコンピュータを自由に操作できてしまうためです。そのような背景においてCookieはWebサーバからWebブラウザ上にデータを残すことのできる例外的な仕組みです。
CookieはPHPの連想配列のようにキーと値の組み合わせでデータを管理します。ただし、 Cookieには様々な制約があります。たとえば1つのキーに指定可能な値には少量のデータ(数KB程度)しか保存できないようになっています。
Cookieへのデータの保存
WebサーバからWebブラウザ上のCookieにデータを保存するためにはHTTPレスポンスに set-cookie
ヘッダを付与します。具体的には次のようなヘッダフィールドです。
set-cookie: Key1=Value1; path=/
レスポンスの中に上記のような set-cookie
ヘッダが存在する場合、Webブラウザは Cookieに Key1
というキーと Value1
という値のペアを保存します。
Cookie上のデータの送信
Cookieに保存されたデータは、Cookieを作成した同一ドメインへのリクエスト時に、自動的にリクエストのヘッダフィールド( Cookie
ヘッダ)に含まれるようになります。
Cookie: Key1=Value1
あるドメインによってCookieに保存されたデータは、別のドメインへのリクエストに含まれることはありません。
ドメインとは
https://example.com/
におけるexample.com/
の部分を指します。example.com/
で作成されたCookieデータは同一ドメインへのリクエストにのみ含まれます。別のドメイン(たとえばhttps://example.co.jp
など)へのリクエストに含まれることはありません。
Cookieデータの削除
これからChromeを使ってセッションおよびCookieの動作を確認します。結果をわかりやすく表示するために、ここではChrome上の既存のCookieを削除しておきましょう。
Cookieを削除するにはデベロッパーツールを起動して「Application」タブを選択します。サイドバーに「Cookies」というセクションがあるので、現在アクセスしているドメインを選択します。中央のパネルで Cookieに保存されている項目の一覧が表示されるので PHPSESSID
という項目があれば削除しておいてください。
PHPSESSID
とはをPHPのセッションIDを意味します。WebブラウザとWebサーバ間でこのセッションID(PHPSESSID
)を使ってセッションを管理します。
PHPプログラムの開発(セッションの仕組み)
ここではさきほどのログイン処理でのやりとりをもとに、実際にどのようなデータ通信が発生してCookieへのアクセスが発生するのかを確認してみましょう。
ビルトインWebサーバを起動した状態で、Webブラウザからログイン画面( login.html
)にアクセスします。
https://〜.vfs.cloud9.ap-northeast-1.amazonaws.com/login.html
ログイン画面が表示されるのでデベロッパーツール(Networkタブ)を開いた状態でIDに Andy
、パスワードに secret
と入力してログインボタンをクリックしましょう。そうするとログイン処理( login.php
)へのHTTP通信と、リダイレクト後のメニュー画面表示処理( menu.php
)へのHTTP通信2つのキャプチャーが取得できます。
ここではまずログイン処理( login.php
)のレスポンスを確認してみましょう。
このレスポンスはメニュー画面表示処理へのリダイレクトを指示しているので、ステータスコードは 302
、また Location
ヘッダには遷移先である menu.php
が指定されています。このとき Cookie
にデータを保存する set-cookie
ヘッダが付与されている点に注意してください。
set-cookie: PHPSESSID=atd3ukr5hsc158ggalu2jfe39n; path=/
この set-cookie
ヘッダによって、 Cookieに PHPSESSID
キーで atd3ukr5hsc158ggalu2jfe39n
という値が保存されます。この PHPSESSID
という名前のキーはセッションIDと呼ばれるものです。この場合、ユーザのセッションID( PHPSESSID
)は atd3ukr5hsc158ggalu2jfe39n
となり、Webサーバ上でユーザのセッションを識別する用途に利用します。
セッションを実現するために必要なネットワーク上のやりとりはセッションIDに限定されます。 $_SESSION
変数に保存した "id"
や "time"
キー、またそれぞれのキーに紐づく値は、セッションIDと関連付けられてサーバサイドに保存されます。
さいごにHTTPレスポンスになぜ、このような set-cookie
ヘッダが付与されたのかという疑問が残ります。これはログイン処理( login.php
)において session_start
関数を呼び出しているためです。PHPでは session_start
関数を呼び出すことで、セッションの管理に必要なHTTPレスポンス(この場合 set-cookie
ヘッダ)を生成するようになっています。
set-cookie
ヘッダの挙動を上手く動作確認できない場合は、デベロッパーツールの「Application」タブからCookieのPHPSESSIDを削除してから試してください。
以上の結果としてログイン処理( login.php
)のレスポンスを受け取ったWebブラウザはCookieに PHPSESSID
キーと atd3ukr5hsc158ggalu2jfe39n
のような値を保持することになります。
続いてChromeのデベロッパーツール(Networkタブ)から、リダイレクト時のメニュー画面表示処理( menu.php
)へのリクエストも確認しておきましょう。
このリクエストはさきほどの set-cookie
ヘッダを受信した際のドメインと同一ドメインへのリクエストに該当するので、リクエストには Cookie
ヘッダが付与されているのがわかります。
cookie: __Host-previewc9corsvfs_9cUgC45nBy87BGFr=9cwVFQmF9S33Cz2rD813CqUEkhmisxoV; AWSALB=EeucH0/h8tHVca6kUAOIDUfZcVDaXpGLe9BlMDBG6mKUH4luwCot7KveEQq8eEZso9r7Ig9TNPb2w2wTKn4ITJC7jKh3iylAquAxY3cy18D1qw/wC01lONzgx8p/; AWSALBCORS=EeucH0/h8tHVca6kUAOIDUfZcVDaXpGLe9BlMDBG6mKUH4luwCot7KveEQq8eEZso9r7Ig9TNPb2w2wTKn4ITJC7jKh3iylAquAxY3cy18D1qw/wC01lONzgx8p/; PHPSESSID=atd3ukr5hsc158ggalu2jfe39n
Cloud9 は独自でCookieを利用しているためいくつかのパラメータが混在します。さいごの部分に
PHPSESSID=atd3ukr5hsc158ggalu2jfe39n
を確認できます。
WebブラウザからWebサーバに送信される cookie
ヘッダはPHPプログラムから参照可能です。またサーバ上にはユーザ(セッションID)に紐づくセッション情報が複数存在します。メニュー画面の表示処理( menu.php
)において、 session_start
関数を呼び出すことで、このセッション情報の一覧の中から送信されたセッションID( PHPSESSID
)に紐づく1件のセッション情報を識別できるようになります。このようにして $_SESSION
変数が利用できるようになります。
まとめ
- 一般的にセッションはCookieを使って実装されている
- Cookieはクライアント(Webブラウザ)上に少量のデータを保存する仕組み
- PHPはセッションを開始するとCookieにセッションIDを保存し、セッションに保存したデータそのものはサーバサイドに保存する