hoge blog

webエンジニア。適当なことしか書きません

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すれば、

元々ユーザーがユーザーデータとして保持していた情報は破棄されるので、ログアウトされるという事になります。

 

 

という感じで、コードゼロの非常に読みづらい記事になりましたが、

ちょうど昨日ハマったお話だったので(死者蘇生の事実に気づけず時間を食いました)、

自分なりにまとめてみました。以上!ヽ(・∀・ )ノ 

 

本日もおそまつさまでしたー( ゚Д゚ノノ☆パチパチ