背景
CakePHP開発で、未ログイン時のリダイレクト処理があり、ユーザー環境なら正しいページにリダイレクトされるが、管理画面環境だとURLが正しくならない問題が発生したので調べました。
前提その1
Authコンポーネントを利用している場合、Auth::allow()
で指定したURL 以外の場合、自動的にリダイレクトする。
リダイレクト先は、Auth::loginAction
の設定に準ずる。
リダイレクト処理は以下参照。
https://github.com/cakephp/cakephp/blob/2.x/lib/Cake/Controller/Component/AuthComponent.php#L366
という仕様である。
基本的に、以下の様に設定されているのが標準。
// AnyControll.php
$this->Auth->loginAction = array(
'controller' => 'user',
'action' => 'login'
);
前提その2
Controller::redirect()
で string
で指定すればそのURLへリダイレクトされるが、配列で以下のように指定できる。
// string
$controller->redirect('/user/login');
=> /user/login へ
// array
$controller->redirect(array('controller' => 'user', 'action' => 'login'));
=> /user/login へ
通常のページの場合、結果は同じになる。
しかし、管理画面等でプレフィックスルーティング設定をしている場合、/admin
以下での挙動は以下のようになる。
// core.php
Configure::write('Routing.prefixes', array('admin'));
// string
$controller->redirect('/user/login');
=> /user/login へ
// array
$controller->redirect(array('controller' => 'user', 'action' => 'login'));
=> /admin/user/login へ
今回の問題はこれ。
前提その3
リダイレクトの引数から実際のURLを生成しているのは、Router::url()
https://github.com/cakephp/cakephp/blob/2.x/lib/Cake/Routing/Router.php#L829
ここで、$url
が配列の場合は、プレフィックスルーティングの設定有無により、プレフィックスを動的に付ける処理が発生するため、今回のように、ログインが共通の場合は、明示指定して上げる必要がある。
解決策
この様に、prefix
と admin
(これはプレフィックスルーティングの設定値次第) に指定すればよい。
// core.php
Configure::write('Routing.prefixes', array('admin'));
// AnyController.php
$this->Auth->loginAction = array(
'controller' => 'user',
'action' => 'login',
'prefix' => null,
'admin' => false,
);