2009-11-05 23 views
8

CakePHP Wersja 1.2.5Komponent CakePHP Auth przy użyciu 2 tabel

Chciałbym, aby pojedynczy użytkownik miał wiele adresów e-mail.
Chciałbym, aby pojedynczy użytkownik miał jedno hasło.
Chciałbym, aby użytkownicy logowali się przy użyciu dowolnego z ich wielu adresów e-mail i ich pojedynczego hasła.

Utworzyłem tabelę użytkowników z polem id i hasłem.
Utworzyłem tabelę user_email_addresses z polem id a pole user_id i pole email_address.

Pytanie:
Jak zmodyfikować komponentu minimalnie auth szukać „username” w tym przypadku „email_address”, w tabeli user_email_addresses i „hasło” w tabeli użytkowników?

Wydaje się, że można to zrobić, modyfikując metodę identyfikacji w komponencie auth. Ale myślę, że modyfikowanie komponentu auth bezpośrednio jest złym pomysłem - wszelkie pomysły na to, jak rozszerzyć i ewentualnie zmodyfikować metodę identyfikacji? http://cakebaker.42dh.com/2009/09/08/extending-cakephps-core-components/ lub ewentualnie wyznaczyć inny obiekt uwierzytelniający?

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

Odpowiedz

8

AuthComponent::identify() przyjmuje dwa parametry $user i $conditions

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

patrząc na powyższym fragmencie, jeśli przejdą false jako $conditions metoda wykona bez warunki modelu.

Również patrząc na pozostałej części kodu, jeśli przekazać wartość $user typu string, nie będzie wykonywać większość kodu związanych użytkownika, aż robi się tutaj:

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

tutaj uruchamia Model::escapeField(), bez parametrów, które zwraca domyślną wersję z domyślną wersją User.id i odwzorowuje to pole na łańcuch, który został przekazany. Następnie łączy to z tablicą $conditions i wykonuje Model::find().

Należy bezpiecznie powiedzieć, że jeśli ciąg jest identyfikatorem użytkownika i nie ma żadnych warunków, za każdym razem znajdzie osobę z tym identyfikatorem.

Jako taki powinien być w stanie przedłużyć AuthComponent robić to, co chcesz tak:

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

Trzeba będzie wymienić wszystkie odniesienia do auth z AppAuth w aplikacji chyba śledzić ten handy tip (the podejście w komentarzach jest miłe).

+0

Dziękuję deizel - dokładnie to, czego szukałem! – BWelfel

Powiązane problemy