2009-11-05 89 views
8

CakePHP版本1.2.5CakePHP驗證組件使用2表

我想單個用戶有多個電子郵件地址。
我想讓一個用戶擁有一個密碼。
我希望用戶使用他們的多個電子郵件地址和他們的單個密碼登錄。

我已經創建了一個帶有ID和密碼字段的用戶表。
我創建了一個user_email_addresses表,其中包含一個id字段,一個user_id字段和一個email_address字段。

問:
如何修改的身份驗證組件最小在這種情況下,「EMAIL_ADDRESS」去尋找「用戶名」,在user_email_addresses表和用戶表中的「密碼」?

好像修改身份驗證組件中的身份識別方法可能會這樣做。但我認爲直接修改auth組件是一個壞主意 - 關於如何擴展和仍然可能修改識別方法的任何想法? http://cakebaker.42dh.com/2009/09/08/extending-cakephps-core-components/或可能指定一個不同的身份驗證對象?

起跑線774:

function identify($user = null, $conditions = null) { 
    if ($conditions === false) { 
     $conditions = null; 
    } elseif (is_array($conditions)) { 
     $conditions = array_merge((array)$this->userScope, $conditions); 
    } else { 
     $conditions = $this->userScope; 
    } 
    if (empty($user)) { 
     $user = $this->user(); 
     if (empty($user)) { 
      return null; 
     } 
    } elseif (is_object($user) && is_a($user, 'Model')) { 
     if (!$user->exists()) { 
      return null; 
     } 
     $user = $user->read(); 
     $user = $user[$this->userModel]; 
    } elseif (is_array($user) && isset($user[$this->userModel])) { 
     $user = $user[$this->userModel]; 
    } 

    if (is_array($user) && (isset($user[$this->fields['username']]) || isset($user[$this->userModel . '.' . $this->fields['username']]))) { 

     if (isset($user[$this->fields['username']]) && !empty($user[$this->fields['username']]) && !empty($user[$this->fields['password']])) { 
      if (trim($user[$this->fields['username']]) == '=' || trim($user[$this->fields['password']]) == '=') { 
       return false; 
      } 
      $find = array(
       $this->userModel.'.'.$this->fields['username'] => $user[$this->fields['username']], 
       $this->userModel.'.'.$this->fields['password'] => $user[$this->fields['password']] 
      ); 
     } elseif (isset($user[$this->userModel . '.' . $this->fields['username']]) && !empty($user[$this->userModel . '.' . $this->fields['username']])) { 
      if (trim($user[$this->userModel . '.' . $this->fields['username']]) == '=' || trim($user[$this->userModel . '.' . $this->fields['password']]) == '=') { 
       return false; 
      } 
      $find = array(
       $this->userModel.'.'.$this->fields['username'] => $user[$this->userModel . '.' . $this->fields['username']], 
       $this->userModel.'.'.$this->fields['password'] => $user[$this->userModel . '.' . $this->fields['password']] 
      ); 
     } else { 
      return false; 
     } 
     $model =& $this->getModel(); 
     $data = $model->find(array_merge($find, $conditions), null, null, 0); 
     if (empty($data) || empty($data[$this->userModel])) { 
      return null; 
     } 
    } elseif (!empty($user) && is_string($user)) { 
     $model =& $this->getModel(); 
     $data = $model->find(array_merge(array($model->escapeField() => $user), $conditions)); 

     if (empty($data) || empty($data[$this->userModel])) { 
      return null; 
     } 
    } 

    if (!empty($data)) { 
     if (!empty($data[$this->userModel][$this->fields['password']])) { 
      unset($data[$this->userModel][$this->fields['password']]); 
     } 
     return $data[$this->userModel]; 
    } 
    return null; 
} 

回答

8

AuthComponent::identify()有兩個參數,$user$conditions

if ($conditions === false) { 
     $conditions = null; 
} elseif (is_array($conditions)) { 
     $conditions = array_merge((array)$this->userScope, $conditions); 
} else { 
     $conditions = $this->userScope; 
} 

看着上面的代碼,如果你通過false作爲$conditions,該方法將不執行模型條件。

} elseif (!empty($user) && is_string($user)) { 
     $model =& $this->getModel(); 
     $data = $model->find(array_merge(array($model->escapeField() => $user), $conditions)); 

     if (empty($data) || empty($data[$this->userModel])) { 
       return null; 
     } 
} 

這:

而且,看代碼的其餘部分,如果你通過string類型的$user值,也不會直到它得到這裏執行大多數用戶相關的代碼運行Model::escapeField(),沒有參數,它會返回User.id(默認情況下)的轉義版本,並將此字段映射到傳入的字符串。然後將其與$conditions陣列合併,並執行Model::find()

應該很安全地說,如果字符串是用戶的ID並且沒有條件,那麼每次都會找到具有該ID的人。

因此,你應該能夠延長AuthComponent做你想要的東西,像這樣:

// app/controllers/components/app_auth.php 
<?php 
App::import('Component', 'Auth'); 
class AppAuthComponent extends AuthComponent { 
/** 
* Custom user identification 
*/ 
    function identify($user=null, $conditions=null) { 
     // get the model AuthComponent is configured to use 
     $model =& $this->getModel(); // default is User 
     // do a query that will find a User record when given successful login data 
     $user = $model->find('first', array('conditions' => array(
      'EmailAddress.' . $this->fields['username'] => $user[$this->userModel][$this->fields['username']], 
      'User.' . $this->fields['password'] => $user[$this->userModel][$this->fields['password']], 
     )); 
     // return null if user invalid 
     if (!$user) { 
      return null; // this is what AuthComponent::identify would return on failure 
     } 
     // call original AuthComponent::identify with string for $user and false for $conditions 
     return parent::identify($user[$this->userModel][$model->primaryKey], false); 
    } 
} 
?> 

你將不得不更換所有引用您的應用程序與AppAuth未與AUTH除非你按照這個handy tip(中在評論中的做法很好)。

+0

謝謝deizel - 正是我在找什麼! – BWelfel