CakePHP 3 AuthComponent Multiple Passwords

Hello,

I am using CakePHP and the AuthComponent, and I want each user to have 2 different passwords. My application has 2 login pages, a frontend login and a backend login. I want users to be able to use one password for frontend login, and a different password for backend login.

I was able to setup the pages so that they have the correct forms on the correct pages

echo $this->Form->control('password', ['type'=>'password']);

:arrow_up: for the main frontend login, and :arrow_down: for the backend login

echo $this->Form->control('backend_password', ['type'=>'password']);

This works in the sence that the correct things are displayed on the correct pages, and I modified my AuthComponent config to this in an attempt to make it work:

        $this->loadComponent('Auth', [
            // 'allowedActions'
            'authError' => 'You are not authorized to access this page.',
            'authenticate' => [
                'Form' => [
                    'fields' => ['username' => 'email', 'password' => 'password'],
                    'fields' => ['username' => 'email', 'password' => 'backend_password']
                ]
            ],
            'loginRedirect' => [
                'controller' => 'Users',
                'action' => 'dashboard'
            ],
            'logoutRedirect' => [
                'controller' => 'Users',
                'action' => 'login'
            ],
            'authorize' => 'Controller',
            'storage' => 'Session'
        ]);

but that isn’t working, the above config makes it so you can only login using the backend login page.

I need an AuthComponent config that accepts both for login.

Thanks in advance for any help you can provide!

By declaring the fields key twice in your Form array, you overwrite the first one with the second. That’s why you can only log in on the backend with this setup. I’m not sure there’s an easy way around this.

'authenticate' => [
    'Form' => [
        'fields' => ['username' => 'email', 'password' => 'password'],
    ],
    'Form' => [
        'fields' => ['username' => 'email', 'password' => 'backend_password']
    ],
],

would seemingly add two authenticators, each with their own field configuration, but that suffers from the exact same issue.

I wonder if putting two use declarations at the top of the file, using the Form authenticator under two different names, and then giving those names here might work, but I suspect not, and I don’t have a good platform to try that on.

You could presumably declare your own BackendFormAuthenticate class, extending (but adding nothing at all to) the standard FormAuthenticate, and then use BackendForm as a custom authenticator for the second array key in the authenticate configuration above?

I tried the code example you gave, and that didn’t work as you suspected.

I couldn’t figure out how to do the second or third suggestion, I am still learning PHP and Cake, and those went over my head. Could you please explain in a bit more detail what I would be doing for the third one?

Thanks again for the help.

I would use two different methods for the two logins. Then you can manage the form, post data, and the query for each situation in a simple, isolated manner.

Anything lengthy I might write here would only be a summary of what’s on the link I provided (and the section immediately above that, about creating custom auth objects), so I’ll let them speak for themselves. The specifics to your situation would be to use

class BackendFormAuthenticate extends FormAuthenticate { }

with literally nothing inside the { }. So all you’re doing really is creating an alias for that class. (It still seems like there should be a better way to do so, but I’m unconvinced that my ideas about it would work given that you need to provide a namespace and class name to the Auth configurator.)

Hope that helps.

I’ve one more suggestion :slight_smile:
You can use “setUser()”.
Create 2 different method for frontend users and backend users.

And match their password according to method and manually login them to site using this “$this->Auth->setUser($user->toArray());”

Check this
https://book.cakephp.org/3/en/controllers/components/authentication.html#manually-logging-users-in

Oops! I just realized I never updated this thread with how I actually solved the issue.

Basically, the backend login form has a hidden checkbox called “backend”, with the value of 1 (checked). In the controller, I look for that, and if I see it I temporarily set the Auth config to use the secondary password.

if($this->request->getData('backend') == 'true') {
    $this->Auth->setConfig('authenticate', [ 
        'Form' => [
            'fields' => [
                'username' => 'email',
                'password' => 'backend_password'
            ]
        ]
    ]);
}

Inserting the above at the top of the controller worked. If anyone else is looking to do this, don’t forget to update your registration function so the user can set both passwords, and they are both actually being hashed. Using this method will (correctly) be expecting the passwords in the database to be hashed.