2007年06月29日

redirect()で困ったら〜"Don't redirect directly!"

ログイン認証まわりでつまずいている方が多いようなので、参考情報を書いておきます……。

Cakeには、

「すべてのアクションの前には、親玉app_controller.php の "beforeFilter"が呼ばれる」

というルールがあります。


[追記:各コントローラにbeforeFilterを独自に設定してしまえば、parent::beforeFilter();としないかぎり、app_controller.phpのbeforeFilter()は呼ばれませんね。「すべてのアクションの前には、“コントローラで独自にbeforeFilterを設定していなければ”、親玉app_controller.phpのbeforeFilterが呼ばれる。独自設定していれば、各コントローラの独自beforeFilterが呼ばれる。独自にbeforeFilterを設定していて、それでも親app_controller.phpのbeforeFilterを呼び出したい、という場合には parent::beforeFilter()とする」としたほうが、正確ですネ。]

別のフレームワークでは、アクションチェインなどというのに似ているでしょうか。なので、ここでログインしているかどうかをチェックすれば、門番として立派な役目を果たすと期待できます。

ただ問題はここからです。

1)ログインしていないことが判明
2)ログイン画面へ飛ばす

というこの簡単な流れをだれでも考えますが、1)のアクションで app_controller.phpのbeforeFilter() を通ったあと、単純に 2)に $this->redirect('ログイン画面用アクション')として飛ばしてしまうと、CPU100%になったり、Firefoxに、“リダイレクトがおかしい”と言われて止まったりしてしまいます。

なぜなら、2)に入った時点でも、「もう一度、app_controller.php のbeforeFilter()が呼ばれる」からです。

つまりは何も考えずにコーディングしてしまうと、app_controller.phpのbeforeFilter() から、app_controler.phpのbeforeFilter()へ、同じところをぐるぐると回るだけになってしまいます。

このあたりを解決するには幾つかの方法があります。

(1)そもそも$this->redirectを使わない
  例えば、$this->layout = "login.thtml"なととして、レイアウトを変更してしまうというアイデアです。

いちばん簡単な認証システム
http://cakephp.seesaa.net/article/20317502.html

(2)DBやセッションに、“今、ログイン作業をはじめたよ”と情報を書き込んでおき、その場合にはリダイレクトしない。(この方法だと、3回ログインに失敗したらアウト、などの処理もできます。)

othauth
http://bakery.cakephp.org/tags/view/othauth
☆このコンポーネントがいまのところ、一番、最先端をいっているコンポーネントです。ただbeforeFilter内に置いて設定するだけで、あとはよしなに取り計らってくれます。

YACCA Yet Another Cake Component for Auth
http://bakery.cakephp.org/articles/view/yacca-yet-another-cake-component-for-auth

(3)今現在、ログインアクション中ならば、リダイレクトしない

if($this->action != 'login' && $this->action != 'logout')

でチェックしています。

http://bakery.cakephp.org/articles/view/simple-form-authentication-in-1-2-x-x

では、bakery.cakephp.org自体のソースコードはどうなっているんだろう、と見てみると、(1)から(3)には該当していませんでした。(4)番目の方法です。

(4)user_controller(=ログインをチェックするコントローラ)内に自分がいるかどうかをチェックする


if(($action != null && $this->action === $action) || $this->action === 'edit' || ($this->action === 'add' && $this->params['controller'] != 'users')){


という仕方でチェックしていました。

いろいろありますね!
posted by SDozono at 11:27| 東京 🌁| Comment(0) | TrackBack(0) | CakePHP Tips | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前: [必須入力]

メールアドレス:

ホームページアドレス:

コメント: [必須入力]

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。

この記事へのトラックバック
手(パー)To make a comment: Please type your name and comment. at the validation field box, type 'cakephp'. And there two glay buttons. "Preview"/"Submit". Thank you!