2009-11-05 10 views
8

CakePHPバージョン1.2.52テーブルを使用したCakePHP認証コンポーネント

私は単一のユーザに複数のメールアドレスを持たせたいと思います。
私は単一のユーザーに1つのパスワードを持たせたいと思います。
複数のメールアドレスと1つのパスワードのいずれかを使用してログインさせていただきたいと思います。

私はidフィールドとpasswordフィールドを持つusersテーブルを作成しました。
idフィールドとuser_idフィールドとemail_addressフィールドを持つuser_email_addressesテーブルを作成しました。

質問:
どのように私は、ユーザーテーブルで、この場合は、「ユーザー名」を探すためにuser_email_addressesテーブルの「EMAIL_ADDRESS」、および「パスワード」を認証コンポーネントの最低限を変更できますか?

authコンポーネントのidentifyメソッドを変更したように見えます。しかし、私は認証コンポーネントを直接変更することは悪い考えであると考えています。 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()あなたは$conditionsとしてfalseを渡した場合、メソッドはなしで実行され、二つのパラメータ、上記のスニペットを見て$user$conditions

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

を取りますモデル条件。また

、あなたがタイプstring$user値を渡した場合、それはここになるまで、それはユーザ関連コードのほとんどを実行しないであろう、残りのコードを見て:

} 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; 
     } 
} 

ここでは、 Model::escapeField()はパラメータなしで実行され、エスケープされたバージョンのUser.id(デフォルト)を返し、このフィールドを渡された文字列にマップします。次に$conditions配列とマージしてModel::find()を実行します。

文字列がユーザーのIDで条件がない場合は、そのIDのユーザーを毎回見つけることができます。

そのように、あなたがそうのようにやりたいAuthコンポーネントを拡張することができる必要があります:あなたはこのhandy tip(従わない限り

// 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へのすべての参照を交換する必要がありますコメントのアプローチはいいです)。

+0

ありがとうございましたdeizel - 私が探していたものです! – BWelfel

関連する問題