Search code examples
cakephpaccess-controlcakephp-3.xrbac

how to create user role wise access control in user and role table joining in cakephp 3?


user table

enter image description here

role table

enter image description here

I just want to allow access control to role table set like: ctrl_view = 1 means this role can view any controller view.

How can I set different action in different role?


Solution

  • Follow conventions, user_role_id should be named "role_id", role_id only "id" and user_name should be "username" or inside your Auth configuration change the default fields name use for your connection form.

    public function initialize() 
        {
    //...
        $this->loadComponent('Auth', [
                  'loginRedirect' => [
                    'controller' => 'Pages',
                    'action' => 'welcome',
                    'prefix' => 'admin' 
                  ],
                  'logoutRedirect' => [
                    'controller' => 'Users',
                    'action' => 'login',
                    'prefix' => false
                  ],
                  'authError' => 'Unauthorized access...',
                  'authenticate' => [
                    'Form' => [
                      'fields' => ['username' => 'user_name', 'password' => 'password']
                    ]
                  ],
                  'authorize' => 'Controller',
                  'unauthorizedRedirect' => [
                      'controller' => 'Pages',
                      'action' => 'unauthorized'
                    ],
                ]);
    // ...
    }
    

    and inside your Appcontroller make somtehing like this

     public function isAuthorized($user)
          {
    
              if(!is_null($this->Auth->user())): // if user is logged
    
                $action = $this->request->getParam('action'); // get name action
    
                $this->loadModel('Roles'); // load your model Roles
                $query = $this->Authorizations->find() // find inside Roles
                ->where([
                'Roles.role_id IN' => $user['user_role_id'], // where role_id is like user_role_id of current user
                'Roles.ctl_'.$action => 1 // and where ctl_[action] is set to 1
                ])->toArray();
    
                if (!empty($query)): // if we find an occurence, we allow the action
                  return true;
                else: // else we don't authorize
                  return false,
                endif;
    
                /* previous lines can be change with this  ----> return (!empty($query)); */
              else: // if user is not connected we don't allow action
                return false
              endif;
        }
    

    and to finish, i think it's better to use "prefix", with prefix u can simplify your authorisation process (will no prefix i allow, with prefix i check my role table), for this you have to simply add these line in the beginin of your isAuthorized function:

    if (!$this->request->getParam('prefix')) {
        return true;
    }
    

    Hope it helps