CakePHP3のAuthコンポーネントで処理されるログイン後のリダイレクト先URLを固定する方法について

f:id:moshimore:20180917234121j:plain
CakePHPで認証処理といえば、Authコンポーネントですが、このコンポーネントには気がかりな仕様が1点組み込まれていました。
その仕様を解決する方法を説明します。

ログイン後のリダイレクト先URL

主な部分だけを掲載しますが、通常はログイン後のリダイレクト先URLとして、以下のように設定します。
この設定では、ログイン後にArticlesコントローラーのindexページにリダイレクトされます。
但し、この設定通りに遷移してくれるのは、「認証が必要ではないページからログインページへアクセスした場合」や「直接、ログインページにアクセスした場合」に限ります。

<?php
public function initialize()
{
parent::initialize();
$this->loadComponent('Auth', [
'loginRedirect' => [
'controller' => 'Articles',
'action' => 'index'
]
]);
}
?>

気がかりな仕様

Authコンポーネントによって、認証が必要なページにアクセスすると、自動的にログインページが表示されます。
その後、ログインすると、loginRedirectの設定は無視され、元のページへリダイレクトされます。
便利な機能ではありますが、ログイン後のリダイレクト先URLを固定することができません。

元のページのURL

ログインページからログインした後に「元のページのURLはどこから取得しているのか」というと、redirectというパラメータから取得しています。
例えば、次のような感じで、元のページはUsersコントローラーのviewページになります。

https://example.com/users/login?redirect=%2Fusers%2Fview

リダイレクト先URLを固定する

redirectというパラメータが存在しなければ、loginRedirectで設定したページへ遷移してくれるので、redirectが設定されないようにしましょう。
その「redirectが設定されない」設定が、どこかにあるかと探してみましたが、残念ながら見つかりませんでした…。
仕方がないので、あまり触れたくはないのですが、Authコンポーネントのソースを変更します。

Authコンポーネントのソースを変更

変更と言っても、redirectパラメータを設定している部分だけなので、1行追加と1行コメントアウトするだけです。
CakePHP自体のアップデートの際に元通りになってしまうであろう事が不安ですが…。

修正箇所は、本日時点(2019/5/5)の最新版で、
「\vendor\cakephp\cakephp\src\Controller\Component\AuthComponent.php」の395行目になります。

// return $controller->redirect($this->_loginActionRedirectUrl());
return $controller->redirect($this->_config['loginAction']);

_loginActionRedirectUrl()の処理では、ログインページのURL($this->_config[‘loginAction’])に元のページがある場合はその情報を付け足しています。
この元のページの情報が不要なので、$this->_config[‘loginAction’]だけを$controller->redirectに設定してあげます。

Cookbookに記載されている仕様

尚、redirectパラメータについては以下のように説明されています。
CakePHP3.4.0より前の場合は、セッションのAuth.redirectの値を削除する必要がありそうです。
例えば、以下のような感じになりそうです。

$this->request->session()->delete('Auth.redirect');

パラメーターが渡されない場合、返される URL は、次の規則に従います。

  • redirect クエリー文字列が存在していて、同じドメインの現在のアプリが実行されている場合は、 正規化された URL を返します。 3.4.0 より前は、セッションの Auth.redirect の値が 使用されていました。
  • クエリー文字列やセッション値がなく loginRedirect の設定がある場合は、 loginRedirect の値を返します。
  • セッションがなく loginRedirect がない場合は、 / を返します。

https://book.cakephp.org/3.0/ja/controllers/components/authentication.html

まとめ

loginRedirectに設定したリダイレクト先を固定にできる設定があれば最適ですが、意外と簡単に思うように変更できました。

以上、CakePHP3のAuthコンポーネントで処理されるログイン後のリダイレクト先URLを固定する方法についてでした。