2014-07-08 21 views
0

我有我的数据库中的两个表,一个用于管理员(名为管理员),另一种为普通用户,命名为:utilisateurs(法语)。我知道我必须使用cakePHP的约定,它说我必须创建一个名为users的表,它具有用户名和密码字段。但问题是我有两张桌子,而不是一张桌子。每个人都有其特定的领域,所以我真的需要他们保持分离。甚至需要登录信息取决于用户是不同的:CakePHP的验证两个表(型号)

  • 管理员需要他们的登录+密码

  • 普通用户需要一个特定ID(以身份证)+密码

我想要做什么,是创建两个登录页面,一个管理员和其他正常用户。登录后,用户被重定向到他应该看到的页面。但是,如果用户试图尝试禁止的位置。我希望能够阻止他(beforeFilter + isAuthorized我认为)

我怎样才能使所有的工作?

我不是在CakePHP的初学者,我已经使用验证组件anotehr应用进行认证的系统,但因为只需要一个表用户,这是一个更容易一些。

你的帮助会非常感激。

+3

这通常是已经被设计失败。尝试将所有用户保留在同一个表中 - 并通过角色区分它们。 而且应该总是只有一个登录页面。 保持简单。 – mark

+0

由于外键约束,我无法将所有用户保留在同一张桌子上,例如: 员工属于某个部门,而管理员不属于任何位置。当然,用户表将会有一个指向部门表的外键。如果我想创建一个管理员帐户,我不能只在department_id上放置任何内容或为null。这只是其中一个例子。我认为设计不失败! – codeless

+2

@codeless为什么不把null放在department_id上?此外,还有其他一些方法可以设计数据库,例如为所有用户共用的数据(例如,登录名和密码)提供用户表,然后拥有与您关联的管理表和常规用户表用户表中包含管理员或常规用户唯一的字段。 – Kai

回答

0

假设如下:

  • 你必须与模型UserAdmin,其中相关的2个表:
    • Useridcardpassword领域。
    • Adminloginpassowrd领域。
  • 使用User::hasPasswordAdmin::hasPassword函数对密码进行散列。
  • 您的登录表单创建如下:

    echo $ this-> Form-> create(null,''); echo $ this-> Form-> input('login'); echo $ this-> Form-> input('password'); echo $ this-> Form-> end(__('Submit'));

可以App/Controller/Component/Auth/MyAuthenticate.php下创建新Authenticate组件:

<?php 

App::uses('FormAuthenticate', 'Controller/Component/Auth'); 

class MyAuthenticate extends FormAuthenticate { 

    public function authenticate(CakeRequest $request, CakeResponse $response) { 

     $username = $request->data['login'] ; 
     $password = $request->data['password'] ; 

     App::import('Model', 'User') ; 
     $userModel = new User() ; 

     /* Try to authenticate as a user... */ 
     $user = $userModel->find('first', array(
      'conditions' => array(
       'idcard' => $username, 
       'password' => User::hashPassword($password) ; 
      ) 
     )) ; 

     if ($user) { 
      $user = $user['User'] ; // Get only useful info 
      $user['type'] = 'user'; // Save user type 
      return $user ; 
     } 

     /* Same thing for admin. */ 

     App::import('Model', 'Admin') ; 
     $adminModel = new Admin() ; 

     $user = $adminModel->find('first', array(
      'conditions' => array(
       'login' => $username, 
       'password' => Admin::hashPassword($password) ; 
      ) 
     )) ; 

     if ($user) { 
      $user = $user['Admin'] ; // Get only useful info 
      $user['type'] = 'admin'; // Save user type 
      return $user ; 
     } 

     return null ; 

    } 

}; 

你只需要确保,一个管理员不能被认证为用户,并扭转。

在你AppController

public $components = array(
    'Auth' => array(
     'authenticate' => array('My'), // The prefix in front of your component 
     'loginAction' => array(/* ... */), 
     'loginRedirect' => array(/* ... */), 
     'logoutRedirect' => array(/* ... */), 
     'authError' => "...", 
     'authorize' => 'Controller' 
    ) 
) ; 

你的登录操作是一样的,对正常表:

public function login() { 
    if ($this->request->is('post')) { 
     if ($this->Auth->login()) { 
      $this->redirect($this->Auth->redirect()); 
     } 
     else { 
      $this->request->data['password'] = "" ; 
      $this->Session->setFlash('Invalid login/id or password.'); 
     } 
    } 
} 

然后,在beforeFilterisAuthorized您可以检查$this->Auth->user('type');。例如,在AppController中:

public function isAuthorized() { 
    /* Assuming you keep CakePHP convention where action starting with admin_ set admin params. */ 
    if(isset($this->params['admin'])) { 
     return $this->Auth->user('type') == 'admin' ; 
    } 
    return true ; 
} 

或者,如果您希望禁用非管理员用户访问在AdminController所有行动,使用beforeFilter

class AdminController extends AppController { 

    public function beforeFilter() { 
     if (!$this->Auth->loggedIn()) { 
      $this->Session->setFlash('You need to be logged to access this page.'); 
      $this->redirect(/* Login url. */) ; 
      return ; 
     } 
     if ($this->Auth->user('type') != 'admin') { 
      $this->Session->setFlash('You need to be admin to access this page.'); 
      $this->redirect(/* Somewhere... */) ; 
      return ; 
     } 
     return parent::beforeFilter() ; 
    } 

} 
+0

谢谢,我稍后再试。我会告诉你结果。 – codeless

+0

对不起,我没有弄清楚你的答案,你能告诉我更多的细节,比如写在哪里(在哪个文件中)以及我应该放什么而不是三点:$ password = $ request-> data ['.. 。']; – codeless

+0

请注意,如果您应用此解决方案,您将需要记住检查Auth :: user('id')是否属于管理员或简单用户的*所有*您的代码取决于它。只要想一想,这可能导致哪些疯狂的安全漏洞(即保存由id为123的管理员创建的一些数据,并且由具有相同ID的普通用户可见)。这就是为什么蛋糕不这样做。你当然可以扩展AuthComponent来为用户使用Auth :: user(),为管理员使用一个新的Auth :: admin(),但这可能无法证明这种痛苦,并且更容易合并您的模型。 – user221931