2

I have an Auth process which works fine with one userModel. But not only because of my DB schema I need to have one login method/action which works with multiple models.

So far I've tried everything I was able to think of or find online - for example editing this Cake 1.3 solution into Cake 3 and a few more hints I was able to find.

However, I'm not able to figure it out.

Thank you for any answer.

My AppController component load:

$this->loadComponent('ExtendedAuth', [
    'authenticate' => [
        'Form' => [
            //'userModel' => 'Admins',
            'fields' => [
                'username' => 'email',
                'password' => 'password'
            ]
        ]
    ],
    'loginAction' => [
        'controller' => 'Admins',
        'action' => 'login'
    ],
    // If unauthorized, return them to page they were just on
    'unauthorizedRedirect' => $this->referer(),
]);

My ExtendedAuthComponent:

class ExtendedAuthComponent extends AuthComponent
{

    function identify($user = null, $conditions = null) {

        $models = array('Admins', 'Users');

        foreach ($models as $model) {

            //$this->userModel = $model; // switch model
            parent::setConfig('authenticate', [
                AuthComponent::ALL => [
                    'userModel' => $model
                ]
            ]);

            $result = parent::identify(); // let cake do its thing

            if ($result) {
                return $result; // login success
            }
        }
        return null; // login failure
    }
}

EDIT1: Description of situation

I have two separate tables (Admins, Users). I need just one login action which tries to use Admins table prior to Users. Because of the application logic I can't combine them to one table with something like 'is_admin' flag. So basically what I need is instead of one specific userModel set in Auth config, I need a set of models. Sounds simple and yet I'm not able to achieve it.

EDIT2: Chosen solution

Based on the answer below, I decided to update my schema. Auth users table is just simplified table with login credentials and role and other role-specific fields are then in separate tables which are used as a connection for other role-specific tables. Even though the answer is not exactly a solution for the asked question, it made me think more about any possible changes of the schema and I found this solution because of it so I'm marking it as a solution. I appreciate all comments as well.

  • It's always helpful to describe what the specific problem is that you are facing with your code, ie what _exactly_ do you expect it to do, and what _exactly_ is it doing instead? (btw, this should probably better be implemented in custom authentication adapters, as it shouldn't be the components concern where and how the adapters do lookup data). – ndm Apr 06 '18 at 13:54
  • @ndm Thanks for your comment. I've tried to describe the situation better in "EDIT1". Hope it will be useful. – Vojtěch Šalda Apr 06 '18 at 14:29
  • That is failure by design, a classical beginners mistake. Use only one single users table and use roles (role_id) etc with additional tables if needed. But never use multiple users table, this gets you in trouble real soon real deep. – mark Apr 06 '18 at 14:33

1 Answers1

4

As Mark already said in a comment: Don't use two users tables. Add a type field or role or whatever else and associated data in separate tables if it's different like admin_profiles and user_profiles.

Don't extend the Auth component. I wouldn't recommend to use it anymore any way because it's going to get deprecated in the upcoming 3.7 / 4.0 release. Use the new official authentication and authorization plugins instead.

If you insist on the rocky path and want to make your life harder, well go for it but then you should still not extend the auth component but instead write a custom authentication adapter. This is the right place to implement your custom 2-table-weirdness. Read this section of the manual on how to do it.

floriank
  • 25,546
  • 9
  • 42
  • 66
  • Thank you for your answer. This is my first app with CakePHP 3 - used CakePHP 2 before. In all my previous apps I had either one table with roles, exactly as you all say, or more tables but then I used prefixes and separated actions - different situation where I want to have different environment for each userType. I will search for improvements of new auth over the basic AuthComponent. – Vojtěch Šalda Apr 08 '18 at 07:38
  • I heard it was getting deprecated in 3.7? And there are so many applications using it, I don't think it'll be a hard deprecation. In my case, I'm using CakeDC/users which would use it. But for smaller, simpler applications with a longer deadline than say next month, I'd probably recommend the authenticate plugin. – meder omuraliev Apr 10 '18 at 19:40
  • Btw, did you mean to link to https://github.com/cakephp/authentication? – meder omuraliev Apr 17 '18 at 13:41
  • Thanks, fixed it :) – floriank Apr 17 '18 at 14:59