2009-11-05 10 views
8

CakePHP Version 1.2.5CakePHP Auth Komponente mit 2 Tabellen

Ich möchte, dass ein einzelner Benutzer mehrere E-Mail-Adressen hat.
Ich möchte, dass ein einzelner Benutzer ein einziges Passwort hat.
Ich möchte, dass sich Benutzer mit einer ihrer mehreren E-Mail-Adressen und ihrem einzigen Passwort anmelden.

Ich habe eine Benutzer-Tabelle mit einer ID und einem Passwort-Feld erstellt.
Ich habe eine user_email_addresses-Tabelle mit einem ID-Feld ein user_id-Feld und ein email_address-Feld erstellt.

Frage:
Wie modifiziere ich die Auth Komponente minimal für den „username“ in diesem Fall zu suchen, „email_address“, in der user_email_addresses Tabelle und das „Passwort“ in der Benutzer-Tabelle?

Scheint, als ob das Ändern der Identifizierungsmethode in der Auth-Komponente es tun könnte. Aber ich denke, dass das Ändern der Auth-Komponente direkt eine schlechte Idee ist - irgendwelche Ideen, wie man die Identifizierungsmethode erweitern und möglicherweise noch modifizieren kann? http://cakebaker.42dh.com/2009/09/08/extending-cakephps-core-components/ oder möglicherweise ein anderes authentifiziertes Objekt vorschlagen?

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

Antwort

8

AuthComponent::identify() nimmt zwei Parameter, $user und $conditions

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

bei dem oben Schnipsel Sehen, wenn Sie false als $conditions geben, wird das Verfahren mit nicht ausführen Modellbedingungen.

Auch im Rest des Codes suchen, wenn Sie einen $user Wert vom Typ string passieren, wird es nicht die meisten der benutzerbezogenen Code ausführen, bis es hier bekommt:

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

Here Läuft Model::escapeField(), ohne Parameter, die eine maskierte Version von User.id (standardmäßig) zurückgibt und dieses Feld auf die Zeichenfolge, die übergeben wurde. Es führt dann das Array $conditions und führt eine Model::find().

Es sollte sicher sein, dass wenn die Zeichenfolge die ID des Benutzers ist und keine Bedingungen vorliegen, die Person mit dieser ID jedes Mal gefunden wird.

Als solche sollten Sie in der Lage sein Auth Komponente zu erweitern zu tun, was Sie wie so wollen:

// 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); 
    } 
} 
?> 

Sie alle Verweise zu ersetzen haben mit AppAuth in Ihrer Anwendung von Auth, wenn Sie diese handy tip (die folgen Ansatz in den Kommentaren ist nett).

+0

Danke deizel - genau das, was ich gesucht habe! – BWelfel

Verwandte Themen