Edited at

CakePHP プレフィックスを無視してリダイレクト先を設定


背景

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 が配列の場合は、プレフィックスルーティングの設定有無により、プレフィックスを動的に付ける処理が発生するため、今回のように、ログインが共通の場合は、明示指定して上げる必要がある。


解決策

この様に、prefixadmin(これはプレフィックスルーティングの設定値次第) に指定すればよい。

// core.php

Configure::write('Routing.prefixes', array('admin'));

// AnyController.php
$this->Auth->loginAction = array(
'controller' => 'user',
'action' => 'login',
'prefix' => null,
'admin' => false,
);