Auth Component
El Auth component o componente de autentificación se utiliza para definir los permisos de los usuarios o grupos en CakePHP. Generalmente se usa en la sección "admin" de la aplicación por lo cual debe activarse el Routing admin.
Routing admin
Routing admin es una constante que indica que en la aplicación de CakePHP existe una zona "admin" o de administración, esta zona debe ser restringida. Para activarlo se debe ubicar y descomentar en el archivo app/config/core.php la línea que dice:
Configure::write('Routing.admin', 'admin');
Esto quiere decir que puedes ir a una liga como http://localhost/admin/entries/listing donde el controlador es entries_controller.php (un controlador típico) y el método es admin_listing() que a su vez usa la vista app/views/entries/admin_listing.ctp. Otro ejemplo es http://localhost/admin/lessons/edit/7 donde el controlador es lessons_controller.php, el método es admin_edit($lesson_id) y la vista es app/views/lessons/admin_edit.ctp.
Auth component
El componente Auth se usa colocándolo en el archivo app/app_controller.php, este archivo es especial: se ejecuta antes de cualquier otro controlador y hereda sus métodos y atributos a todos los demás controladores pues define el Auth en el método beforeFilter, un método de CakePHP que como el nombre lo indica, coloca un filtro previo antes de ejecutar cualquier cosa. Guarda este archivo en el directorio app/.
Este archivo importa el componente Auth para toda la aplicación. Es importante hacer notar que estamos usando el email y no el username para hacer el logeo. Las partes más importantes de la configuración de Auth son:
$this->Auth->authorize = 'controller';
Esto quiere decir que los permisos serán definidos en cada controlador en lugar de revisar los permisos en la base de datos usando ACOs.
$this->Auth->deny('*');
Esto es: todas la acciones de todos los controladores están prohibidas a menos de que se diga lo contrario en el controlador. Sólo hay dos acciones que pueden usarse: login() y logout() del controlador users_controller.php.
Si las indicaciones del componente Auth están colocadas en app_controller.php (como lo acabamos de hacer) significa que cada uno de nuestros controladores necesita dos métodos extras, el método beforeFilter() y el método isAuthorized().
public function beforeFilter() // esté método se ejecuta antes que todos
{
$permissions = array('display', 'view'); // array con métodos públicos
parent::beforeFilter();
if ( $this->Auth->user() ): // True si el usuario está logeado
array_push($permissions, 'edit', 'preview'); // estos métodos sólo para usuarios logeados
endif;
$this->Auth->allow($permissions); // coloco permisos
}
public function isAuthorized()
{
if (isset( $this->params[Configure::read('Routing.admin')] )): // si estoy en la zona admin
if ( $this->Auth->user('group_id') == 1 ): // si soy un usuario logeado y del grupo admin
return true; // Welcome!
endif;
endif;
return false; // go away !!
}
$this->Auth->allow(array('display', 'view')) del método beforeFilter() define en cada controlador que acciones están disponibles sin seguridad, en este caso display y view son accesibles a cualquiera que llegué a nuestro sitio. En Karamelo el método isAuthorized sirve para restringir la zona admin del panel de control y es genérico pues está colocado una sola vez en el archivo app_controller.php para no colocar el mismo código en cada controlador.
Login y Logout
Necesitamos el controlador 'users' para manejar el login y el logout de nuestro blog:
<?
//File: app/controllers/users_controller.php
class UsersController extends AppController {
public function login()
{
$this ->layout = 'portal';
}
public function logout()
{
$this->Cookie->del('User');
$this->Session->destroy();
$this->Session->setFlash('Logout');
$this->redirect($this->Auth->logout());
}
}
?>
Necesitamos una vista para el formulario de logeo:
//archivo: app/views/users/login.ctp
< ?
echo $form->create('User', array('controller' => 'users', 'action' => 'login'));
echo $form->input('email'); // <- NOTA: estoy usando el email y no el username
echo $form->input('pwd');
echo $form->end('Login');
?>
Nos colocamos en http://localhost/users/login y debemos ver el formulario de logeo. Si escribimos nuestro correo y password debemos entrar como usuarios logeados al blog. En los controladores usamos:
echo $this->Auth->user('username') . ' '. $this->Auth->user('email') . ' '.$this->Auth->user('id');
Para ir por la información del usuario logeado, por ejemplo para consultar sólo los registros que le pertenecen en un modelo:
$conditions = array('Model.user_id'=>$this->Auth->user('id'));
También lo usamos antes de guardar un registro que requiere un user_id:
$this->data['Model']['user_id'] = (int) $this->Auth->user('id');
Puedes ver la zona admin del entries controller para ver un ejemplo.
Por otro lado en las vistas y layouts usamos el helper session para consultar la info del usuario logeado, por ejemplo en nuestro layout portal.ctp tenemos una parte que dice:
if ( isset( $session->read('Auth.User.username') ) )
Este array de session es colocado en las vistas y layouts por app_controller.php siempre y cuando el usuario este logeado. Es decir que siempre tendrás este array disponible en las vistas si quieres mostrar o conocer la información de un usuario.
Hash password
Nunca se deben guardar directamente los passwords en la base de datos pues esto es un serio riesgo en la seguridad de nuestra aplicación, antes de guardar un password en cualquier lugar, se debe hacer un "hash" al string del password, CakePHP hace esto automáticamente usando la encriptación MD5. Es importante hacer notar que este hash se basa en el string Salt del archivo APP/config/core.php, por eso CakePHP nos pide que cambiemos este Salt recién cuando los instalamos. Este string Salt debe respaldarse en un lugar seguro para no perderlo pues si alguien cambia este Salt ningún usuario podrá ya logearse pues el hash del formulario /users/login ya no coincidirá con el hash guardado en la base de datos. Una forma rápida de revisar como Cake encripta el password es colocar la siguiente línea en el método beforeFilter() del archivo APP/app_controller.php
die('PWD hashed: '. AuthComponent::password($this->data['User']['pwd']));
Si este string no concuerda con el de la BD quiere decir que fueron generados usando diferentes Salt strings. Una manera fácil de resolver esto (si es un caso único y no un error de la aplicación) es hacer un update al campo pwd del usuario de la BD usando el string generado por esta línea.
