2014-07-08 40 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