Cakeには、
というルールがあります。
[追記:各コントローラに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')){
という仕方でチェックしていました。
いろいろありますね!