Revista Tecnología

Laravel 5.4: Guardar información de un usuario en un Token mediante JWT

Publicado el 24 julio 2017 por Juan Ricardo Castro Lurita @pepoflex

Demo Github

Parte fundamental de una Rest API es enviar la data por medio de un token el cual nos ayuda a mantener la seguridad de la información de los usuarios. Las aplicaciones en este caso para Android no soporta sesiones ni cookies, solo debemos almacenar la data del usuario en el celular via Shared, en este tutorial vamos a meter la información privada del usuario mediante JWT en Laravel 5.4, vamos con el tutorial.

Desplegando JWT

Voy a usar JWT hasta la actualidad es la mejor tecnología para enviar y recibir información privada entre 2 puntos, para este caso desde el servidor hasta la aplicación.

Laravel 5.4: Guardar información de un usuario en un Token mediante JWT

Fuente: jwt.io

Bien yo hice Fork a la librería tymon/jwt-auth a mi repositorio https://github.com/pepoflex/jwt-auth, allí esta su url real del repositorio, lo que hacemos es despegarla en nuestro proyecto Laravel 5.4, para ello abrimos nuestro archivo composer.json y lo instanciamos:

"require": {
    "tymon/jwt-auth": "0.5.*"
}

Abrimos nuestra consola de comando y ejecutamos el siguiente comando para actualizar los paquetes de nuestro proyecto:

$ composer update

Luego abrimos nuestro archivo app.php y colocamos en sus correspondientes lugares:

Providers:

'Tymon\JWTAuth\Providers\JWTAuthServiceProvider'

Facades:

'JWTAuth' => 'Tymon\JWTAuth\Facades\JWTAuth' 
'JWTFactory' => 'Tymon\JWTAuth\Facades\JWTFactory'

Paso seguido en nuestra consola de comandos ejecutamos el siguiente comando para publicar la libreria desplegada en nuestro proyecto:

$ php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\JWTAuthServiceProvider"

Por ultimo ejecutamos el siguiente comando para generar un llave secreta para gestionar nuestros Tokens JWT:

$ php artisan jwt:generate

Gestionando nuestro Middleware

Ejecutamos el siguiente comando para crear nuestro Middleware que nos da una capa de seguridad para restringir el acceso a ciertas partes de nuestra aplicación:

$ php artisan make:middleware VerifyJWTToken

A este Middleware le agregamos la siguiente estructura:

VerifyJWTToken.php

<?php

namespace App\Http\Middleware;

use Closure;
use JWTAuth;
use Tymon\JWTAuth\Exceptions\JWTException;
use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;


class VerifyJWTToken
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        try{
            $user = JWTAuth::toUser($request->input('token'));
        }catch (JWTException $e) {
            if($e instanceof \Tymon\JWTAuth\Exceptions\TokenExpiredException) {
                return response()->json(['token_expired'], $e->getStatusCode());
            }else if ($e instanceof \Tymon\JWTAuth\Exceptions\TokenInvalidException) {
                return response()->json(['token_invalid'], $e->getStatusCode());
            }else{
                return response()->json(['error'=>'Token is required']);
            }
        }
       return $next($request);
    }
}

Ahora abrimos nuestro archivo Kernel e instanciamos el Middleware y el Refresh Token que actualiza a un token nuevo por cada request que haga tu aplicación:

Kernel.php

protected $routeMiddleware = [
        'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
        'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
        'can' => \Illuminate\Auth\Middleware\Authorize::class,
        'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
        'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
        'jwt.auth' => \App\Http\Middleware\VerifyJWTToken::class,
        'jwt.refresh' => 'Tymon\JWTAuth\Middleware\RefreshToken',
        'cors' => \Barryvdh\Cors\HandleCors::class,
        'ability' => 'App\Http\Middleware\TokenEntrustAbility::class'
        //'csrf' => 'App\Http\Middleware\VerifyCsrfToken',
    ];

Ruta a mi Método Login

Creamos la ruta para que la aplicacion acceda y pueda leer el método login de nuestro controlador que crearemos en el paso siguiente. Abrimos el archivo api.php y colocamos la ruta:

Route::middleware('auth:api')->get('/user', function (Request $request) {
    return $request->user();
});

Route::post('p/login', 'ApiController@login');

Colocando la data en un token

Nota: Voy a exportar los datos del usuario en un token y aparte la la data pura en JSON para que puedan comparar los datos limpios y dentro de un token.

Creamos un controlador llamado ApiController:

ApiController.php

$ php artisan make:controller ApiController

Paso seguido creamos nuestro objeto login para la autenticación de un usario, veamos:

<?php

namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use JWTAuth;
use App\User;
use JWTAuthException;
use Tymon\JWTAuth\Providers\AbstractProvider;
use Tymon\JWTAuth\Providers\ProviderInterface;
use Validator;
use Response;
use Auth;

class ApiController extends Controller
{
    public function login(Request $request){
        $credentials = $request->only('email', 'password');

        //$pasajero = User::first();

        //Almaceno los datos del usuario en mi variable $customClaims:
        $customClaims = ['datos' => User::first()];

        $token = null;
        try {
           //Llamo a mi varaible $customClaims para generar el token con los datos del usuario:
           if (!$token = JWTAuth::attempt($credentials, $customClaims)) {
            return response()->json(['Usuario o Contraseña incorrectos'], 422);
           }
        } catch (JWTAuthException $e) {
            return response()->json(['Error al crear el token'], 500);
        }

        // Dentro de mi variable $user voy a generar el token con los datos del usuario mediante JWTAuth::toUser() metodo nativo de la librería que instanciamos:
        $user = JWTAuth::toUser($token);

        // Retorno los datos dentro de un token en formato JSON:
        return response()->json(compact('token', 'user'));
    }
}

Ejecuto mi ruta login en POSTMAN y obtengo mi JSON de datos:

Laravel 5.4: Guardar información de un usuario en un Token mediante JWT
Ahora que ya tenemos copiaré el token y lo pegare en mi JWT debugger para decodificar la data de mi token, obtengo la data decodificada que contenía mi token:

Laravel 5.4: Guardar información de un usuario en un Token mediante JWT
Bien ahora lo único que te queda es almacenarla en tu aplicación y gestionar todos los datos del usuario mediante tokens.

Bueno eso es todo, síguenos en nuestras redes sociales y nos vemos hasta un próximo articulo.


Volver a la Portada de Logo Paperblog