2009-11-05 17 views
8

CakePHP Versión 1.2.5Componente Auth de CakePHP con 2 tablas

Deseo que un solo usuario tenga varias direcciones de correo electrónico.
Me gustaría que un solo usuario tenga una sola contraseña.
Me gustaría que los usuarios inicien sesión usando cualquiera de sus múltiples direcciones de correo electrónico y su contraseña única.

He creado una tabla de usuarios con un id y un campo de contraseña.
He creado una tabla user_email_addresses con un campo id. Un campo user_id y un campo email_address.

Pregunta:
¿Cómo modificar el componente de autenticación mínimamente a buscar el "nombre de usuario" en este caso, "email_address", en la tabla user_email_addresses y la "contraseña" en la tabla de usuarios?

Parece que modificando el método de identificación en el componente de autenticación podría hacerlo. Pero creo que modificar directamente el componente de autenticación es una mala idea: ¿alguna idea sobre cómo extender y aún posiblemente modificar el método de identificación? http://cakebaker.42dh.com/2009/09/08/extending-cakephps-core-components/ o posiblemente nominar un objeto autenticado diferente?

Línea de salida 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; 
} 

Respuesta

8

AuthComponent::identify() toma dos parámetros, $user y $conditions

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

Mirando el fragmento anterior, si pasa false como el $conditions, el método se ejecutará sin condiciones modelo

También, mirando el resto del código, si pasa un valor de tipo $userstring, no va a ejecutar la mayor parte del código relacionada con el usuario hasta que se pone aquí:

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

Aquí ejecuta Model::escapeField(), sin parámetros, que devuelve una versión de escape de User.id (de forma predeterminada) y asigna este campo a la cadena que se pasó. A continuación, combina esto con la matriz $conditions y realiza un Model::find().

Debería ser seguro decir que si la cadena es la identificación del usuario y no hay condiciones, encontrará a la persona con esa identificación cada vez.

Como tal, debe ser capaz de extender AuthComponent a hacer lo que quiere de este modo:

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

que tendrá que reemplazar todas las referencias a AUTH con AppAuth en su aplicación a menos que siga este handy tip (la enfoque en los comentarios es bueno).

+0

Gracias deizel - ¡exactamente lo que estaba buscando! – BWelfel

Cuestiones relacionadas