[PHP] Usando el modulo de autenticación Kohana A1

Kohana A1, es un modulo de kohana el cual nos permite implementar de una forma efectiva, potente y clara, un sistema de autenticación, de una forma fácil y sencilla.

Antes de empezar a usarlo es importante considerar que el modulo usa la el constructor crypt de PHP pero usando como hash CRYPT_BLOWFISH, esto no afecta si estas usando PHP 5.3, pero si tienes este inconveniente al final del post pondré como solucionarlo(o cambiarte de hosting a uno mas actualizado).

Vamos a ver como usarlo para hacer un login.

Requisitos:

  • Kohana 3.2
  • Kohana A1 module
  • Kohana ORM
  • Kohana Database

Como dicen los requisitos para usar A1 debemos de estar conectados a una base de datos, también debemos de tener un modulo que abstraiga dicha base de datos, para esto podemos usar Kohana ORM, Automodeler, Jelly, Sprig o entre otros, si estamos haciendo pruebas yo recomiendo usar Kohana ORM, y ya en base a sus requerimientos y necesidades usar el que mas les agrade.

Instalamos kohana de modo que quede en http://localhost/kohana1/ ,creamos una base de datos yo la llamare, “system” y le pondré como datos de conexión ultra-seguros user:root password:root, recuerden activar el modulo database y ORM.

Y posteriormente nos toca, agregar el siguiente código SQL a nuestra base de datos, obviamente lo pueden modificar a su gusto, aunque de momento dejémoslo así.

Ahora procedemos a bajar el modulo A1, que esta aquí: https://github.com/Wouterrr/A1/

Y lo ponemos en nuestro carpeta modules nombrando a la carpeta A1 de modo que quedara asi “modules/A1″.Dentro de dicha “modules/A1″ hay una carpeta config y dentro de ella un archivo llamado a1.php, bien este archivo es el archivo de configuración del modulo Kohana A1, de igual forma que se hace con todos los módulos hay que copiar este archivo a “application/config/” para poder editarlo y que no afecte directamente al modulo.

El archivo se ve de la siguiente forma:

Aquí pongo la descripción de cada elemento:

    • driver: EL ORM que usara (ORM,jelly,mango,sprig[se pueden agregar mas pero hay que modificar el modulo o extenderlo])
    • user_model: tabla(modelo) que se usara ‘user’
    • cost: fuerza (tamaño de la clave) entre 4 y 31, lo ideal es 12, si ponen un numero muy grande tomar en cuenta que consumirá mas recursos.
    • cookie: los datos de la cookie que generara a1, para hacer el login(nombre y duración)
    • columns: aquí le estamos asignando a los items de A1, las columnas de la base de datos, es decir si en su base de datos el nombre de usuarios están en el campo nombre, tendrán que poner ‘username’ => ‘nombre’, modificando lo que esta en el array, los campos opcionales de momento no los usaremos, aunque cabe señalar que solo guardan información extra.
    • session: Aquí es donde definimos el tipo de sesión, de momento y regularmente bastara con dejarlo como esta, si su aplicación correrá en varios servidores conviene ponerlo en modo database(aunque en este caso hay que hacer un par de cosas mas, espero postear pronto sobre esto)

.

No se les olvide activar le modulo en el bootstrap, el cual en la sección módulos debería verse así:

<?php
//more code
/**
 * Enable modules. Modules are referenced by a relative or absolute path.
 */
Kohana::modules(array(
	// 'auth'       => MODPATH.'auth',       // Basic authentication
	// 'cache'      => MODPATH.'cache',      // Caching with multiple backends
	// 'codebench'  => MODPATH.'codebench',  // Benchmarking tool
         'A1'         => MODPATH.'A1',           //A1 authentication
	 'database'   => MODPATH.'database',   // Database access
	// 'image'      => MODPATH.'image',      // Image manipulation
	 'orm'        => MODPATH.'orm',        // Object Relationship Mapping
	// 'unittest'   => MODPATH.'unittest',   // Unit testing
	// 'userguide'  => MODPATH.'userguide',  // User guide and API documentation
	));

Ahora vamos a crear un controlador que sera en este caso el backend, el cual verificara que si estas logueado te deja entrar a ejecutar cualquier acción, si no te re-direccionara a un controlador “account” y al action “login” que tendra la vista del formulario de login, y también tendrá un link a registrarse usando este modulo A1.

En este controlador “backend” tenemos una action, llamada index que cargara un vista, en donde mostraremos un mensaje que dirá “bienvenido Nombre_de_usuario”

Las partes importantes a destacar son:

  • En el método before asignamos a $this->auth (variable publica) una instancia de A1, que es el modulo que hará el login.
  • Luego preguntamos mediante el método $this->auth->logged_in() que seria lo mismo que usar A1::instance()->logged_in(), que si es FALSE, significa que no esta logeado entonces lo redirecciona a la siguiente url:
  • Route::url(‘default’,array(‘controller’ => ‘account’, ‘action’ => ‘login’) la cual dice: que usando el route llamado default construya un url basada en cierto controlador, cierta acción y cierto id.
  • Tenemos un action (metodo) index que mostrara una vista que estará en la carpeta backend, la vista se llama home y le digo que envié los datos de autenticación usando la variable auth.

Este es el código del controlador account, con sus metodos/acciones de registro y login.

Como vemos este controlador, tenemos el método before que se ejecuta antes de cualquier “action” en donde establecemos el valor de algunas propiedades de la clase como la autenticación, la sesión y el modelo (entidad).

También le indico que si recibo el método action_index, en realidad ejecute el método action_login, que es el que hará el trabajo.

El método action_login, lo que hace es mostrar la vista login, la cual tiene esta estructura.

Que como vemos, es un simple formulario.

En el mismo método action_index, tiene un if que comprueba si recibe una petición POST, si es así extraemos las variables usando Arr::get de kohana, también verificamos si existe la variable remember, la cual actúa como una FLAG, que en caso de ser verdadero lo usaremos para recordar los datos del usuario.

Aquí es donde ocurre, toda la “magia”, y haremos hincapié en esto.

if($this->auth->login($username,$password,$remember)) :

Este código lo que hace es hacer el login, y el ultimo parámetro remember tiene la capacidad de generar el recordatorio del password.

Si el login es correcto, se creara un sesión y hará la lógica de asignación de variables del usuario a la sesión, posteriormente se redirecciona a el backend del sistema.

En caso de no hacer el login, tenemos anteriormente un array, que en este caso asignara a una clave llamada login, un mensaje de error., el cual se mostrara en la vista login.

También tenemos un método action_register, que posee, un formulario similar al de login, y que en este caso hace el registro de un usuario, usando el modelo users, el cual también hace validación de que no exista un usuario con el mismo nombre(obviamente la validación puede ser diferente).

Y también tenemos el método save_user que es encargado de hacer el insert del nuevo usuario, aquí vemos que usamos para el password, $auth->hash(), que es un método de A1, que lo estamos inyectando como dependencia (DI), y es importante usar este método ya que con esto generamos el password usando el algoritmo de cifrado que incluye A1, aunque lo podremos modificar, pero es indispensable convertir el password al guardarlo, al hacer el login no es necesario convertirlo A1 lo hace en automático.

Regresando al controlador, después de que el nuevo usuario se haya registrado, se redirecciona al login, si no simplemente avisa del error, mandando esta información, a la vista.

En el mismo controlador tenemos un método action_logout, que lo que hace es cerrar la sesión, y redireccionar, aquí creo que no hace falta mas explicación.

En el método after lo que hago es lanzar la vista a la pantalla usando $this->response->body

Quizá un poco larga la explicación pero es mejor que quede claro.

En resumen, creamos nuestro controlador que haga el login, y otro que cree las cuentas, usamos A1, para manejar el password, para registrar el usuario y para hacer el login, evitando volver a reescribir este proceso cada vez que necesitemos hacer un login.

Como nota adicional, verán en el controlador backend un método privado que se llama: _prevent_back(), este método evita que cuando hagamos logout, al dar clic en el botón atrás, no regrese a la sesión como si nunca hubiéramos salido por que esta cacheado, aunque realmente hayamos finalizado la sesión y no permita hacer nada. Estoy en contacto con el creador del modulo y mande la propuesta de agregar este control de cache al core del modulo, y la parecer en breve ya vendrá por default y ya no tendrán que agregar este método(sera configurable desde el archivo de configuración del modulo).

Tambien me falto agregar que el campo de la base de datos para el password, debe de ser de al menos 70-80 caracteres, o más, por que las cadenas que genera A1, para los passwords son muy grandes, y si aumentan el cost en el config, aun seran mas grandes.

Aparte de los gists, dejo el proyecto en github, para que quien guste lo puede tomarlo y bajarlo:

Hasta el próximo post.

Github: kohana A1 implementación.
Parche para usar A1 pero con sha1 si necesidad de usar bcrypt: https://gist.github.com/1352205
Colocar el archivo del parche (a1.php) en application/classes/ y ahora sus password que generen o usen usaran sha1 y no brcypt con CRYPT_BLOWFISH

5 Comentarios

  1. Wlises R. 14 diciembre, 2011 Responder

    Tanta vaina pa’ eso ? y que tan seguro sera !!!
    En CodeIgniter se consigue con su libreria nativa.

  2. Juan 13 mayo, 2012 Responder

    …y que paso con la vista register, no esta??

  3. Alex Arcaya 5 diciembre, 2012 Responder

    Extremadamente sencillo amigo! Gracias por la explicación y los enlaces… un Saludo!

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos necesarios están marcados *

*

Puedes usar las siguientes etiquetas y atributos HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">