(現象)
1. ログイン実行、ログイン成功ならばクッキー変数にセッションIDを設定します。
2. しばらくログインしたままで画面を開いていました。
ガベージコレクションが実行されてプログラム内で設定したセッション変数が削除
されました。
3. ログアウトの処理を実行せず、画面を閉じて終了しました。
明示的にsesson_destroy()は実行していません。
4. 再度ログインしました。その後設定されているセッション変数を確認したところ、
上記1.で設定していたセッションIDと同じ値が設定されました。
2.でガベージコレクションが実行されてセッション変数が
削除されたはずなのに、再度ログインすると同じ以前と同じセッションIDとなる
理由がわかりません。
セッションIDはガベージコレクション実行後でも削除されないのでしょうか。
PHPでセッションIDが変更されるのはどのようなタイミングなのでしょうか。
もしかすると私のphpのセッションの仕様理解不足な点があるかもしれません。
わかる方がおりましたら教えてください。
大まか流れは以下の通りです。
(B)=ブラウザ、(P)=PHPのアクションです。
(B)最初のアクセス
↓
(P)新規セッション、及び新規セッションIDを生成。
クッキーにセッションIDを載せて返送。
↓
(B)セッションIDを記録。
セッションIDをリクエストヘッダに載せて次のページ要求。
↓
(P)ブラウザから送られたセッションIDがまだアクティブ(※1)なので、セッション継続中と判断。
ページ返送(これ以降、クッキーは発行しない)。
↓
(B)セッションIDがまだ有効(※2)なので、セッションIDをリクエストヘッダに載せて次のページ要求。
:
(略)
:
(B)しばらく放置。(その間にPHPのGCが実行される)
:
(B)再度アクセス。
セッションIDがまだ有効(※2)なので、セッションIDをリクエストヘッダに載せて次のページ要求。
↓
(P)ブラウザから送られたセッションIDは無効(※1)と判断。
新規セッションを生成する。但し、セッションIDはブラウザから送られた物をリサイクルする。
(なぜならセッションIDが重複しないのは保証されているから)
-------------------
要点は(※1)と(※2)でセッション切れの判断が異なっている点です。
PHPの(※1)の判断は、php.ini の session.gc_maxlifetimeパラメータで指定された時間で期限切れとなりますが、そんな事はブラウザ側の知ったこっちゃありません。PHPが勝手に(ブラウザに無断で)期限切れと判断しているだけです。
ブラウザの(※2)の判断はサーバーから送られて来るレスポンスヘッダの、クッキーexpiresで指定された時間で判断します。
つまり、(※1)と(※2)できちんと同期が取れているわけでは無いのです。
回答ありがとうございました。
サーバー(PHP)側とブラウザのセッション切れの判定が異なるのが原因ということですね。
現在担当しているアプリケーションでは、
各ページ遷移ごとにPHPからのセッションID(session_id())と
初期ログイン時にcookie変数に設定したsession_id()の
値でユーザがただしくログインしたかを判定しています。
同期がとれていないのであればこの判定方法ではまずいかもしれません。
他にユーザのログイン状態の妥当性を判定する実装方法があるのでしょうか。
また普通は、どのように実装のでしょうか。