セッションは、アクセスしてきた人が次にアクセスした時も同一のマシン環境からかどうかを判別するための仕組みです。
セッションを開始する時には『セッションID』というものを発行します。
これはその場で生成したランダムな文字の並びなのでこの中に情報が盛り込まれているということはありません。
アクセスしてきたユーザとは何の関連性もないただのランダムな文字列を発行することは、セッションIDを他の情報から割り出されないようにするためには重要なことです。
発行したセッションIDは、一方はアクセスしてきた人のブラウザに保存してもらい、もう一方はサーバ側で持っておきます。
このブラウザ保存はクッキーと言われる仕組みを使っているのでブラウザがクッキーを受け入れない設定になっていればこの方法は使えないということになります。
ログイン認証の時には、ユーザ名とパスワードが一致すればセッションIDを発行してログイン状態となります。
そうなると認証以降は送られてきたセッションIDとサーバ側に保存されたセッションIDの合致を見てそこに結び付けられたユーザ名を見ることでユーザ判別ができるようになります。
▼ session_start()の2つの挙動
セッション開始を行うsession_start()には2つの挙動がある。
- セッションIDが送られてこなければセッションIDを発行してクッキー保存するように送り付ける。
- セッションIDが送られてきたら該当するセッション用ファイルを探してその中にデータがあればセッション配列$_SESSIONにセットする。
▼ セッションIDが送られてきたかどうやって判断しているか
session_name()の返す文字がセッションIDのキーになるので、例えばキーが"SID"なら$_COOKIE['SID'], $_POST['SID'], $_GET['SID']のどれかが送られてきたかを見ていることになる。つまり$_REQUEST['SID']一つを見てるのと同じ
▼ 架空のセッションIDを送るとどうなるか
サーバ側が受け取ったセッションIDに該当するファイルを探しに行って、該当ファイルがないということになるとその架空のセッションIDに基づいてファイルが作成されてしまう。この挙動を知らないととんでもないセキュリティホールを作ってしまいかねないので注意。
▼ 架空のセッションIDを弾くには
session_start()が実行される前の段階で、送られてきたセッションIDが正当なものかチェックする必要がある。
セッションIDを他人に入手されてしまった場合、例え有効期限を設定していても期限内であれば不正利用される可能性があります。
こういう場合の対策として、アクセスする度にセッションIDを更新するいわゆるワンタイムセッションという方法があります。
方法はsession_regenerate_id()関数を使えばいいわけですが、この関数はバージョンによって挙動が違うのである程度バージョンの違いを吸収する方法を考えてみます。