CakePHP Auth Component loginRedirect Behavior

Main Thread 2 min read

The other day I noticed some unexpected behavior for one of the web applications I developed in CakePHP using the Auth Component. After logging in, I was redirected to my previously visited page. This would be expected had my session expired or I needed to log in first. However, this occurred after logging out of the web application.

After debugging the login() and logout() actions I noticed that Auth.redirect was not being cleared from the session. I inspected the core file for the Auth Component (auth.php) to see when Auth.redirect updated. It turns out that the startup() method had some interesting code.

1if ($loginAction == $url) {
2 // ...
3 if (!$this->Session->check('Auth.redirect') && !$this->loginRedirect && env('HTTP_REFERER')) {
4 $this->Session->write('Auth.redirect', $controller->referer(null, true));
5 }
6}

The interesting piece is the inclusion of $this->loginRedirect. According to the documentation:

The AuthComponent remembers what controller/action pair you were trying to get to before you were asked to authenticate yourself by storing this value in the Session, under the Auth.redirect key. However, if this session value is not set (if you're coming to the login page from an external link, for example), then the user will be redirected to the URL specified in loginRedirect.

Yet, according to the code above, $loginAction sets Auth.redirect unless it or loginRedirect is set. I added the following code to my Auth Component configuration:

1'Auth' => ['autoRedirect' => false, 'loginRedirect' => '/']

After doing so, I expected that the Auth Component would no longer remember the requested URL if I was not logged in. But, contrary to the documentation, I was still redirected when attempting to access a secure area of the site before logging in.

Honestly, my head exploded on this one. I'm still a little fuzzy on loginRedirect. But here's my two cents. The original issue only occurred after logout. Since logout redirects to loginAction, the referrer was the previously requested page. Although logout() cleared Auth.redirect, the code above stored the referrer in Auth.redirect. Upon setting loginRedirect, the logic above failed. Since this code only runs when $loginAction == $url, it does not prevent Auth from remembering the requested URL when it matters.

I find many developers dislike the Auth Component. Whether it's too complex or not enough features, I don't know. What I do know is there is value in using native functionality. So, to be clear, this post is about the unclear documentation for the loginRedirect property and not bashing the Auth Component.

Find this interesting? Let's continue the conversation on Twitter.