Api Rest con Codeigniter 3 y AngularJS
Api Rest con Codeigniter 3 y AngularJS

En esta entrada vamos a ver cómo podemos crear un sistema de autenticación utilizando Json Web Token (JWT), el cliente lo haremos con angularjs y el servidor con codeigniter, pero es simple implementarlo con nodejs, laravel, ruby o python.

En el tutorial anterior ya vimos que es JWT y lo útil que puede ser en nuestras aplicaciones cuando consumimos servicios rest y necesitamos mantener de alguna forma las sesiones en el lado del cliente, por ejemplo, en angularjs.

Entonces tendremos lo siguiente:

  • Un formulario de login para iniciar sesión.
  • Una vez haga login si las credenciales son correctas crearemos un token con JWT y le daremos 5 minutos de vida.
  • El token lo devolveremos al cliente (angularjs) y utilizando el módulo angular-jwt podremos decodificar su payload.
  • Una vez en el cliente y utilizando el módulo angular-storage guardaremos en localStorage el token proporcionado por el servidor para enviarlo en futuras peticiones.
  • A través del provider jwtInterceptorProvider haremos que de forma automática nuestro token sea envíado en cada petición a través de los headers con un nombre y un prefijo para así capturarlo en el servidor, esto lo podremos hacer de forma dinámica cómo veremos más adelante.
  • Gracias al método run y al evento $routeChangeStart podremos comprobar si nuestro token ha expirado, y si es así mandaremos al usuario fuera de la aplicación.
  • Una vez el usuario esté dentro de la aplicación tendremos un botón para hacer una petición al servidor, recoger allí el token, comprobar si el usuario existe y si es así devolver un JSON con una tabla de películas que creareamos.

Cómo puedes ver tenemos trabajo, pero la idea es coger muchos conceptos y verlos en práctica ya que es la mejor forma de entender cómo funcionan las cosas.

JWT en el servidor

Lo primero que tenemos que hacer es crear nuestro proyecto php, utiliza el framework que quieras, yo lo haré con codeigniter, descargar el archivo JWT.php, guardalo en la carpeta helpers y cargalo en el autoload, así lo tendremos disponible, haz lo mismo con la base de datos.

Aquí tienes la base de datos que vamos a utilizar.

Descargar base de datos

Simplemente tiene dos tablas, accounts y movies.

Ahora crea un nuevo controlador llamado auth.php y dentro añade el siguiente código.


Simplemente hacemos login al usuario, si los datos enviados desde el formulario son correctos entonces debemos crear el token con JWT, y lo más importante de esto es ver cómo añadimos las propiedades iat (time() en el que se creo el token) y exp (time() cuando expira el token), en este caso 5 minutos.

Estas dos propiedades aparte de muchas otras son standard en JWT, por ende el módulo que vamos a utilizar en angularjs tiene un método que comprueba si el token ha expirado, y justamente necesita esta propiedad.

JWT en el cliente con AngularJS

Lo primero que debemos hacer es instalar algunos módulos con bower.

AngularJS:


NgRoute:


Para mantener el token con localStorage:


JWT en AngularJS:


Bootstrap:


Ahora que ya tenemos todo lo necesario podemos crear el directorio statics y dentro guardamos el siguiente archivo obtenido de bootsnipp.

Descargar style.css

Ya tenemos la base de ambos proyectos, crear un archivo index.html y añade el siguiente código típico de cualquier aplicación hecha con angularjs.


Ahora debemos crear el formulario de login, para ello crea un directorio llamado templates y dentro un archivo llamado login.html, a continuación añade el siguiente código.


Por fin llegamos a lo que nos interesa, angularjs, crea tu archivo app.js y añade el siguiente código.


De momento sólo creamos nuestro módulo app e inyectamos los módulos ngRoute, angular-jwt y angular-storage, establecemos una constante y las rutas de nuestra aplicación, ahora necesitamos definir nuestro controlador loginCtrl, así que añade el siguiente código a continuación.


Simple, hacemos una petición a la factoría authFactory y comprobamos el resultado, si todo va bien guardamos el token en localStorage y redirigimos a la home, ahora añade el siguiente código a continuación para crear dicha factoría.


Hacemos la petición post con los datos del formulario (hay que mejorarlo, no es bueno enviar las contraseñas en texto plano) al método login del controlador auth que hemos creado con codeigniter y devolvemos una promesa.

Antes de comprobar si esto funciona debemos crear el controlador home y la template home.html, así que primero crea el controlador a continuación del controlador loginCtrl.


Aquí ya vemos cosas más interesantes, obtenemos el token, cogemos la información perteneciente al usuario y la pasamos a la vista como user, a continuación hacemos una petición a la factoría movies para obtener todas las películas, así que vamos a crear dicha factoría.



Cómo puedes ver, aquí decimos que sí es necesario enviar el token con la propiedad skipAuthorization a false, el resto es igual que antes.

Ahora es momento de crear la template home.html dentro de templates, que será donde podamos visualizar las películas obtenidas y la información del usuario.


Cómo ya habíamos dicho, en cada petición queremos enviar el token a través de los headers, para ello podemos utilizar en la configuración de nuestro módulo en provider jwtInterceptorProvider, así que deja tu sección config de la siguiente forma.


Ahora sólo nos queda crear el método run de nuestro módulo de la siguiente forma.


Esto es muy básico, es mejor utilizar eventos pero para el ejemplo está bien, simplemente comprobamos si existe el token y este no ha expirado, de otra forma lo devolvemos a la pantalla de login.

Para finalizar nuestro trabajo debemos volver al servidor y crear el controlador movies.php, el modelo movies_model.php y el modelo auth_model.php, abre el primero y añade el siguiente código.


Comprobamos si podemos obtener a través de los headers la clave Authorization y si es así decodificamos el token y comprobamos si pertenece a un usuario con checkUser(), si existe el usuario obtenemos las películas y devolvemos un json.

Ahora crea el modelo auth_model.php y añade el siguiente código.


El método login simplemente comprueba si el usuario existe a través del email y el password, y el método checkUser hace lo mismo pero a través del payload del token con las claves id y email.

Ahora crea el modelo movies_model.php y añade el siguiente código con lo que habremos terminado.


Finalmente obtenemos las películas y las devolvemos al controlador, así desde AngularJS ya podemos obtenerlas y mostrarlas en la vista home.html.

Si ahora haces login con los datos [email protected] y 12345678 podrás hacer ir a la home y cuando pulses en el botón verás las películas, de la misma forma, en la parte alta verás el payload del usuario ya que hemos decodificado el token y pasado a la vista como user.

El código completo del ejemplo está en mi repositorio de github, lo puedes obtener y hacer con él lo que quieras.