Seleccionar página

Una de las características que Laravel 5.x nos ha facilitado bastante es la autenticación. Con sólo un comando, habremos generado las rutas, vistas y controladores automáticamente (lo que se conoce como «scaffolding).

Pero aunque esto está muy bien, puede que no se ajuste totalmente a nuestras necesidades. Laravel gestiona la autenticación y sesión entre otras formas, por cookies. ¿Y que pasa si queremos usar tokens para nuestras API’s ? Laravel introduce en su versión 5.2 la autenticación por tokens en rutas «api» de nuestra aplicación.

Esto nos pone las cosas fáciles pero ¿qué pasa si queremos ir más allá y personalizar las respuestas en función del estado de ese token enviado en cada petición? o ¿ qué pasa si queremos usar distintos «guards» mediante paquetes de terceros? Pues bien, en este post, te mostraré como modificar lo que Laravel nos trae por defecto manteniendo las vistas tal y como están para realizar los ejemplos.

Estos son los pasos a seguir:

  • Instalar el paquete JWT-Auth (para la autenticación y manejo de los tokens).
  • Instalar el paquete JWT Guard (para usar jwt como driver de autenticación) aquí.
  • Configurar los drivers de autenticación.
  • Modificar el modelo de usuario «User».
  • Sustituir el middleware de autenticación de Laravel por otro previamente modificado.
  • Realizar las modificaciones necesarias en el paquete JWT-Auth para que funcione el middleware «auth:api» en las rutas.
  • Crear un service provider para poder usar el «guard» que queramos, en nuestro caso con el driver «api», en grupos de rutas.

Empezamos instalando el paquete para usar JWT’s:

Ahora edita el siguiente archivo:

Al acabar, hay que publicar el archivo de configuración de ese paquete y luego establecer la «key» privada que se usará para descifrar los tokens (lo hace JWT-Auth automáticamente y de forma transparente a nosotros).

Turno de JWT Guard:

Añadimos el paquete a nuestro proyecto:

Registramos el Service Provider:

Establecemos del driver de autenticación:

Editamos el modelo User tal que:

Ya que la versión 1.0@dev de jwt-auth no incluye las respuestas JSON en caso de no proporcionar el token en las peticiones o que éste sea inválido o que haya expirado, tenemos 2 opciones:

  • No modificamos ningún archivo y usamos el middleware «jwt.auth» para proteger las rutas que necesiten JWTokens.
  • Modificamos una serie de archivos para poder usar el middleware «auth:api» que viene de serie con jwt guard.

Vamos a hacer un test, abre el archivo de rutas api:

Para usar el middleware «auth:api» modificamos lo siguientes archivos:

  • app\Http\Kernel.php
  • vendor\tymon\jwt-auth\src\Http\Middleware\Authenticate.php
  • vendor\tymon\jwt-auth\src\Http\Middleware\BaseMiddleware.php
  • vendor\tymon\jwt-auth\src\Providers\JWT\Namshi.php
  • vendor\tymon\jwt-auth\src\Exceptions\JWTException.php
  • El resto de archivos en la carpeta de excepciones \vendor\tymon\jwt-auth\src\Exceptions les agregamos una propiedad, nada más.

Vamos uno a uno. Primero comentamos el middleware que trae Laravel y añadimos el nuevo:

Editamos Authenticate.php con el contenido de esta seccion:

Editamos BaseMiddleware.php:

Editamos Namshi.php

Editamos JWTException.php

Y ya por último, el resto de Exceptions añadiendoles una propiedad:

Si navegamos a la ruta «/api/users/create»  el resultado es un token, justo lo que necesitábamos.

Si con el token anterior navegamos a la ruta «/api/users/show?token=token_obtenido_anteriormente» obtendremos los datos del usuario con ID 1 de la base de datos. ¡¡Misión cumplida!!

Por último haremos un hack para que podamos elegir el Guard a aplicar en un grupo de rutas, cuya fuente fue extraida de aqui :

Editamos el archivo generado, tal que:

Y registramos el provider:

Ahora, las rutas de ejemplo quedarían así:

Ahora, accediendo a las rutas que hemos definido, podemos comprobar las respuestas que nos devuelve el middleware de autenticación:

  • Token not provided : cuando no se aporta el token en la url o en las cabeceras de la petición.
  • Token invalid: cuando el token enviado no es válido.
  • Token expired: cuando el tiempo de vida del token haya expirado.

Esta solución es MUY intrusiva ya que hemos modificado archivos que se encuentran en la carpeta «vendor» de Laravel, cosa que no se debe hacer. El motivo es porque cuando actualicemos las dependencias de nuestro proyecto, nos habremos cargado todo este trabajo.

Esto es sólo para salir del paso. Más adelante veremos una solución más elegante y sobre todo, correcta de gestionar la autenticación.

Actualizado:

Tienes la versión no intrusiva en este post.