# CakePHP 5 upgrade and Authentication

**URL:** <https://discourse.cakephp.org/t/cakephp-5-upgrade-and-authentication/12847>\
**Category:** Need Help\
**Tags:** help\
**Created:** [May 10, 2026, 8:45am UTC](https://discourse.cakephp.org/t/cakephp-5-upgrade-and-authentication/12847 "2026-05-10T08:45:32Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![bgrinter](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/bgrinter/32/1381_2.png) [@bgrinter](https://discourse.cakephp.org/u/bgrinter)\
**Post date:** [May 10, 2026, 8:45am UTC](https://discourse.cakephp.org/t/cakephp-5-upgrade-and-authentication/12847/1 "2026-05-10T08:45:32Z")

</div>

I’ve started going through the process to migrate a fairly large app from v4.6 to v5.3.5.

So far, I’ve gone fairly well and I’m presented with a login screen - not too bad for an afternoon’s work 😛

Now that I’m tying to log in, I’ve struck a problem with a supposedly invalid password

In v4 I had the following

```php
            $authenticationService = new AuthenticationService([
                'unauthenticatedRedirect' => Router::url('/users/login'),
                'queryParam' => 'redirect',
            ]);

            // Load identifiers, ensure we check email and password fields
            $authenticationService->loadIdentifier('Authentication.Password', [
                'fields' => [
                    'username' => 'email_address',
                    'password' => 'password',
                ],
                'resolver' => [
                    'className' => 'Authentication.Orm',
                    'userModel' => 'Users',
                    'finder' => 'userDetails' // Customer Finder that returns associated Member record
                ]
            ]);

            // Load the Session impersonate authenticator first, lets us act as proxy on a users account
            $authenticationService->loadAuthenticator(Authenticator\SessionImpersonateAuthenticator::class);
            // Load the authenticators, you want session first
            $authenticationService->loadAuthenticator('Authentication.Session');
            // Configure form data check to pick email and password
            $authenticationService->loadAuthenticator('Authentication.Form', [
                'fields' => [
                    'username' => 'email_address',
                    'password' => 'password',
                ],
                'loginUrl' => Router::url('/users/login'),
            ]);

```

In V5 I have the following

```php
            $authenticationService = new AuthenticationService();

            // Define where users should be redirected to when they are not authenticated
            $authenticationService->setConfig([
                'unauthenticatedRedirect' => [
                    'prefix' => false,
                    'plugin' => false,
                    'controller' => 'Users',
                    'action' => 'login',
                ],
                'queryParam' => 'redirect',
            ]);

            $fields = [
                'username' => 'email_address',
                'password' => 'password',
            ];

            // Load the authenticators. Session should be first.
            // Session just uses session data directly as identity, no identifier needed.
            $authenticationService->loadAuthenticator('Authentication.Session');
            $authenticationService->loadAuthenticator('Authentication.Form', [
                'identifier' => [
                    'className' => 'Authentication.Password',
                    'fields' => $fields,
                ],
                'fields' => $fields,
                'loginUrl' => Router::url([
                    'prefix' => false,
                    'plugin' => null,
                    'controller' => 'Users',
                    'action' => 'login',
                ]),
            ]);

            // Load the Session impersonate authenticator first, lets us act as proxy on a users account
            $authenticationService->loadAuthenticator(Authenticator\SessionImpersonateAuthenticator::class);

```

I’ve tried following the documentation as best I can but I’ve run out of ideas.

Any assistance/greatly appreciated

Regards,  
Brian

---

<div class="post-metadata">

**Author:** ![bgrinter](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/bgrinter/32/1381_2.png) [@bgrinter](https://discourse.cakephp.org/u/bgrinter)\
**Post date:** [May 11, 2026, 4:54pm UTC](https://discourse.cakephp.org/t/cakephp-5-upgrade-and-authentication/12847/2 "2026-05-11T16:54:15Z")

</div>

Managed to get help on slack

Will post outcomes here if I get a chance

---

<div class="post-metadata">

**Author:** ![KevinPfeifer](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/kevinpfeifer/32/3365_2.png) [@KevinPfeifer](https://discourse.cakephp.org/u/KevinPfeifer)\
**Post date:** [May 26, 2026, 9:11am UTC](https://discourse.cakephp.org/t/cakephp-5-upgrade-and-authentication/12847/3 "2026-05-26T09:11:22Z")

</div>

What was the problem? Could something be improved in the docs?

---

<div class="post-metadata">

**Author:** ![bgrinter](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/bgrinter/32/1381_2.png) [@bgrinter](https://discourse.cakephp.org/u/bgrinter)\
**Post date:** [May 26, 2026, 9:37am UTC](https://discourse.cakephp.org/t/cakephp-5-upgrade-and-authentication/12847/4 "2026-05-26T09:37:05Z")

</div>

thread [here](https://cakesf.slack.com/archives/C053DPNGT/p1778511182737879) on slack

ok Claude suggested changing

```auto
$authenticationService->setConfig([
    'unauthenticatedRedirect' => [
        'prefix' => false,
        'plugin' => false,
        'controller' => 'Users',
        'action' => 'login',
    ],
    'queryParam' => 'redirect',
]);

```

to

```auto
$authenticationService->setConfig([
    'unauthenticatedRedirect' => '/users/login',
    'queryParam' => 'redirect',
]);

```

and

```auto
'loginUrl' => Router::url([
    'prefix' => false,
    'plugin' => false,
    'controller' => 'Users',
    'action' => 'login',
]),

```

to

```auto
'loginUrl' => '/users/login',

```

which seems to have done the trick

---

<div class="post-metadata">

**Author:** ![KevinPfeifer](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/kevinpfeifer/32/3365_2.png) [@KevinPfeifer](https://discourse.cakephp.org/u/KevinPfeifer)\
**Post date:** [May 26, 2026, 9:39am UTC](https://discourse.cakephp.org/t/cakephp-5-upgrade-and-authentication/12847/5 "2026-05-26T09:39:19Z")

</div>

ah right, this was more a router config problem than a authentication problem as the “URL-Array” didn’t resolve to the same URL you were expecting.

We will adjust the docs to mention, that either the URL-Array or a simple string can be used in this case.

---

<div class="post-metadata">

**Author:** ![dereuromark](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/dereuromark/32/37_2.png) [@dereuromark](https://discourse.cakephp.org/u/dereuromark)\
**Post date:** [May 26, 2026, 11:58am UTC](https://discourse.cakephp.org/t/cakephp-5-upgrade-and-authentication/12847/6 "2026-05-26T11:58:50Z")

</div>

The Array should usually work just fine and is the clean primary version in v4, so I wonder what made it not work in your case. You are using v4.1+ of the plugin, right?

---

<div class="post-metadata">

**Author:** ![bgrinter](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/bgrinter/32/1381_2.png) [@bgrinter](https://discourse.cakephp.org/u/bgrinter)\
**Post date:** [May 29, 2026, 9:59am UTC](https://discourse.cakephp.org/t/cakephp-5-upgrade-and-authentication/12847/7 "2026-05-29T09:59:39Z")

</div>

yes, 4.1 - bit strange but work now

---

<div class="post-metadata">

**Author:** ![bgrinter](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/bgrinter/32/1381_2.png) [@bgrinter](https://discourse.cakephp.org/u/bgrinter)\
**Post date:** [May 29, 2026, 10:12am UTC](https://discourse.cakephp.org/t/cakephp-5-upgrade-and-authentication/12847/8 "2026-05-29T10:12:17Z")

</div>

Ok hopefully the last issue with authentication - I have an API and under CakePHP4 if would give a nice JSON or XML error

```auto

{

    "message": "Authentication is required to continue",

"url": "/api/members.json?in_unit=350",

"code": 401

}

```

but after upgrading to CakePHP5 and latest authentication plugin I’m getting HTML authentication errors.

---

<div class="post-metadata">

**Author:** ![bgrinter](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/bgrinter/32/1381_2.png) [@bgrinter](https://discourse.cakephp.org/u/bgrinter)\
**Post date:** [May 30, 2026, 6:24am UTC](https://discourse.cakephp.org/t/cakephp-5-upgrade-and-authentication/12847/9 "2026-05-30T06:24:54Z")

</div>

Ok, after it hallucinated a few times for me, Claude helped with the explanation that the error/exception handling stack had changed a bit between 4/5. In 4 the component handled it all for me, but for 5 I had to implement and APiExceptionRenderer - got it working now

---

<div class="post-metadata">

**Author:** ![KevinPfeifer](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/kevinpfeifer/32/3365_2.png) [@KevinPfeifer](https://discourse.cakephp.org/u/KevinPfeifer)\
**Post date:** [May 30, 2026, 8:55am UTC](https://discourse.cakephp.org/t/cakephp-5-upgrade-and-authentication/12847/10 "2026-05-30T08:55:31Z")

</div>

Good to hear that you found a solution.

CakePHP 4.4 introduced a new error and exception handling system which you can find here.

> **[ErrorHandler & ConsoleErrorHandler ​ - 4.4 Migration Guide | CakePHP](https://book.cakephp.org/4.x/appendices/4-4-migration-guide.html#errorhandler-consoleerrorhandler)**
>
> CakePHP 4.4 is an API compatible upgrade from 4.0. This page outlines the deprecations and features added in 4.4. | CakePHP Documentation - The rapid development PHP framework

This means you were able to use the old error system till the next major version.

---

<div class="post-metadata">

**Author:** ![bgrinter](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/bgrinter/32/1381_2.png) [@bgrinter](https://discourse.cakephp.org/u/bgrinter)\
**Post date:** [May 30, 2026, 10:34am UTC](https://discourse.cakephp.org/t/cakephp-5-upgrade-and-authentication/12847/11 "2026-05-30T10:34:57Z")

</div>

Claude - sometimes good, sometimes shit 😛

“That didn’t work”  
“Good catch. CakePHP 5 renamed and restructured the error handling classes. Here’s what changed:”

tell me that the first time 😆

that’s how this happens

> **[Company Blew $500M On Claude AI In One Month Due To No Usage Limit On...](https://finance.yahoo.com/sectors/technology/articles/company-blew-500m-claude-ai-173519468.html)**
>
> Enterprise AI spending disaster unfolds as anonymous company burns $500M on Claude in one month due to unlimited employee access and poor governance controls.

---

<div class="post-metadata">

**Author:** ![KevinPfeifer](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/kevinpfeifer/32/3365_2.png) [@KevinPfeifer](https://discourse.cakephp.org/u/KevinPfeifer)\
**Post date:** [May 30, 2026, 10:40am UTC](https://discourse.cakephp.org/t/cakephp-5-upgrade-and-authentication/12847/12 "2026-05-30T10:40:36Z")

</div>

> [@bgrinter](#):
>
> I’ve started going through the process to migrate a fairly large app from v4.6 to v5.3.5.

this indicated to me, that you have already seen the deprecation for the old error handler 😛

---

<div class="post-metadata">

**Author:** ![bgrinter](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/bgrinter/32/1381_2.png) [@bgrinter](https://discourse.cakephp.org/u/bgrinter)\
**Post date:** [May 30, 2026, 10:55am UTC](https://discourse.cakephp.org/t/cakephp-5-upgrade-and-authentication/12847/13 "2026-05-30T10:55:21Z")

</div>

No - must have missed it, although there were a fair few others
