session_destroyとflashdataの落とし穴 ー うっかり死者蘇生していた件
最近はユーザー認証機構を作っています。
そこで使っているのがCodeIgniterの認証モジュールDX_Authです。
http://codeigniter.com/wiki/DX_Auth/
日本語版はこちらから
http://d.hatena.ne.jp/ozawa34/20091223/1261581994
会員登録、パスワード変更や退会処理等々基本的な認証機構から、
オートログイン、ロールの設定モジュールも入っている優れもの。
特に画像認証やメールのアクティベーション機能には軽く感動してしまいました。
今ちょうどこちらを応用して、
メールアクティベーションでのメールアドレスの変更機能とかを作っている最中です。
さてさて、そんな中でハマったネタを一つ投下しておきます。
【概要】
退会処理機構を作っていた時のお話です。
どんな流れにしようとしていたかというと、
退会フォーム
↓
確認ページ
↓
退会処理(論理削除)、完了直後に強制ログアウト
↓
二重処理防止の為どこぞにリダイレクト(退会メッセージを表示)
そこで問題になったのが、
退会処理後にセッションを破棄しているはずなのに「強制ログアウトされない」問題。
【結論】
を言うと、セッション破棄(memcachedからセッションIDに紐付く情報を削除)直後に、set_flashdata(退会メッセージ)をしていたのが原因でした。
実際に行われていた処理の流れは、
1.退会処理(ユーザーは、ユーザーデータとしてセッションIDやユーザーIDを所持)
↓
2.memcachedからセッションIDに紐付く情報を削除
↓
3.この段階でまだユーザーデータは存在(※次のサーバリクエスト時に抹消される)
↓
4.次のサーバリクエストが行われる前にset_flashdata(CodeIgniterサポートのセッションクラス)
↓
5.ユーザーデータとして存在しているセッションIDにflashdataを上書き
↓
6.次のサーバリクエストでflashdataが保持される為、ユーザデータも保持されたまま
↓
7.強制ログアウト(セッション破棄)されていない状態
という感じ。
破棄したはずのセッションがset_flashdataによって生き返るという、死者蘇生状態だったわけでした^q^
【解決策】
set_flashdataする直前で、手動で新しいセッションを作ってしまう!
要するに上記で言う3と4の間で、session_create的な関数(Sessionライブラリに書いとく)で、強制的に新しいセッション情報を発行してしまえば良いのです。
新しく発行されたセッションに対してset_flashdataすれば、
元々ユーザーがユーザーデータとして保持していた情報は破棄されるので、ログアウトされるという事になります。
という感じで、コードゼロの非常に読みづらい記事になりましたが、
ちょうど昨日ハマったお話だったので(死者蘇生の事実に気づけず時間を食いました)、
自分なりにまとめてみました。以上!ヽ(・∀・ )ノ
本日もおそまつさまでしたー( ゚Д゚ノノ☆パチパチ