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すれば、
元々ユーザーがユーザーデータとして保持していた情報は破棄されるので、ログアウトされるという事になります。
という感じで、コードゼロの非常に読みづらい記事になりましたが、
ちょうど昨日ハマったお話だったので(死者蘇生の事実に気づけず時間を食いました)、
自分なりにまとめてみました。以上!ヽ(・∀・ )ノ
本日もおそまつさまでしたー( ゚Д゚ノノ☆パチパチ
CodeIgniterの仕様とSmarty導入
先日まで暫しSlimというフレームワークを使っていましたが、
今後CodeIgniter2を使うことになります。
基本的な仕様で普通に詰まったのが2点(´・ω・`)
(1)ControllerとModelのクラス名はかぶっちゃいけない!
考えてみたら、まぁ当たり前なのかもしれないのですが、
class Hello extends CI_Controller {
で始まるコントローラーに
class Hello extends CI_Model {
で始めたモデルを読みこませようとしたら、画面真っ白けでした。
何でもいいので
class HelloModel extends CI_Model{
とか、
class Hellos extends CI_Model{
とかいうクラス名に変えとけばおkです。
(2)Controllerのfunction名がそのまんまURIに反映される。
例えば、こんなコントローラーだと、
class Hello extends CI_Controller {
public function __construct()
{
parent::__construct();
$this->load->library('parser');
$this->load->model('Hellos');
}
public function index()
{
$result_array = $this->Hellos->findMember();
foreach ($result_array as $row)
{
echo $row['id'].'<br />';
}
}
public function smartyTest()
{
$data['title'] = "The Smarty parser works!";
$data['body'] = "Smarty!";
$this->parser->parse("hello.tpl", $data);
}
URIはそれぞれClassとfunctionに対応して、
http://www.~~~/hello/
$row['id]が書き出される
(function index()の中身)
http://www.~~~/hello/smartyTest/
hello.tplが呼び出される(このsmarty連携については下記)
(function smartyTest()の中身)
===========================
という感じの、基礎の基礎の仕様が分かってなかったので無駄足を踏みました(ヽ'ω`)
そして、CodeIgniter2とsmarty3の連携についてですが、
これは結論からいうと、素晴らしいライブラリ様があるので、
そちらを使わせてもらうと早いです。
Using Smarty 3 in Codeigniter 2 (a really tiny CI library)
http://ilikekillnerds.com/2010/11/using-smarty-3-in-codeigniter-2-a-really-tiny-ci-library/
1.こちらさんのgithubからzipでファイルをダウンロードし、既存のCodeIgniterのapplicationディレクトリに上書き。
2.readmeに書いてある通り、config/autoload.php に ライブラリ perser を読みこませれば、
Controller+view(tpl) の smartytest が動きます。
詳しく解説して下さってるブログは他にあるのでぐぐってくだしあ。
$HOME/.vimrc と /etc/vimrc の違い【CentOS】
設定ファイル群を設置する位置にはいつも迷う(´・ω・`)
vimrcの置き場もそのひとつ。
よく目にするvimrcの置き場は、ホームディレクトリ直下($HOME/.vimrc)とのこと。
これはユーザー毎の設定ファイルとして機能するもよう。
権限があるサーバーの場合、全ユーザーに適用する設定を記載することもできる。それが、
/etc/vimrc
/etc/vimrc には、デフォルトである程度vimの設定がなされている。
ただし、本来サーバのroot権限を持っていないとここは弄れないので、
ローカル環境のVMの場合等を覗いて、前者の通りホームディレクトリ直下に置くのが正しいようだ。
=================
似た現象として、.htaccess と httpd.conf の関係が当てはまるように思う。
CodeIgniterのURLから、index.phpを抜く処理( http://codeigniter.jp/user_guide_ja/general/urls.html )を行なっていた際、
.htaccess自体が読み込まれていなかったのが原因で、正しく動作しなかった。
その際、直接 /etc/httpd/conf/httpd.conf のバーチャルホスト設定部分に書き込むことで動作した。
※ .htaccessとhttpd.conf も通常編集できる権限に差がある。