Anexsoft | Blog y dictado de cursos de Tecnología

En este encontrarás tutoriales de tecnología como PHP, ASP.NET MVC, Front-End, entre otros y cursos exigentes de modalidad online que te ayudarán a crecer profesionalmente.

Implementación de Json Web Token con PHP
Actualizado el 23 Febrero, 2016 y leído 15,891 veces
Calificación: 10.00 / 10

Implementación de Json Web Token con PHP

Anexsoft

En este ejemplo práctico vamos a autenticar a un usuario usando Json Web Token. Para esto debemos agregar la dependencai mediante Composer.

composer require firebase/php-jwt

 

Generando nuestro Token

Para implementar facilmente nuestro JWT vamos a crear el siguiente script:

require_once 'vendor/autoload.php';

use Firebase\JWT\JWT;

$time = time();
$key = 'my_secret_key';

$token = array(
    'iat' => $time, // Tiempo que inició el token
    'exp' => $time + (60*60), // Tiempo que expirará el token (+1 hora)
    'data' => [ // información del usuario
        'id' => 1,
        'name' => 'Eduardo'
    ]
);

$jwt = JWT::encode($token, $key);

$data = JWT::decode($jwt, $key, array('HS256'));

var_dump($data);

No es nada del otro mundo así que no se asusten

  • JWT::encode recibe 2 parámetros, el primero es la información que queremos que contenga nuestro token y el otro es una cadena que usaremos como key para evitar que otro pueda decodificar nuestro token.
  • La información que contendrá nuestro token esta compuesto por un par de parámetros.
    • iat: es el tiempo que el token inició
    • exp: es el tiempo que el token expirará, por defecto le hemos puesto del tiempo que inicio una hora más.
    • data: es información que queremos que guarde el token, en nuestro caso la información del usuario.

Si corrieron el script y no hubo problema alguno deberán visualizar la siguiente información.

object(stdClass)[3]
  public 'iat' => int 1456170718
  public 'exp' => int 1456174318
  public 'data' => 
    object(stdClass)[4]
      public 'id' => int 1
      public 'name' => string 'Eduardo' (length=7)

 

Validando el Token

Al momento de intentar decodificar el token hubiera algún problema de validación una excepción será arrojada. Para este caso vamos hacer 2 pruebas para arrojar la excepción.

Secret Key incorrecto

En esta prueba, el key ingresado para decodificar el token no es el mismo que se usó para codificarlo.

$jwt = JWT::encode($token, $key);
$data = JWT::decode($jwt, 'SOY OTRO KEY', array('HS256'));

La excepción sería la siguiente:

Signature verification failed

Excedimos el tiempo de expiración

En esta prueba vamos a restarle un segundo al tiempo de expiración.

$time = time();
$key = 'my_secret_key';

$token = array(
    'iat' => $time,
    'exp' => $time--,
    'data' => [
        'id' => 1,
        'name' => 'Eduardo'
    ]
);

$jwt = JWT::encode($token, $key);
$data = JWT::decode($jwt, $key, array('HS256'));

La excepción sería la siguiente:

Expired token

 

Haciendo la vida más sencilla

He creado una clase que permita trabajar de manera más práctica con JWT. Esta nos va a permitir generar el token, almacenar la información del usuario "data" y adicionalmente le agregará mayor seguridad para evitar que usen nuestro token en otro navegador. Por defecto el tiempo de expiración ha sido seteado a una hora.

<?php
use Firebase\JWT\JWT;

class Auth
{
    private static $secret_key = 'Sdw1s9x8@';
    private static $encrypt = ['HS256'];
    private static $aud = null;
    
    public static function SignIn($data)
    {
        $time = time();
        
        $token = array(
            'exp' => $time + (60*60),
            'aud' => self::Aud(),
            'data' => $data
        );

        return JWT::encode($token, self::$secret_key);
    }
    
    public static function Check($token)
    {
        if(empty($token))
        {
            throw new Exception("Invalid token supplied.");
        }
        
        $decode = JWT::decode(
            $token,
            self::$secret_key,
            self::$encrypt
        );
        
        if($decode->aud !== self::Aud())
        {
            throw new Exception("Invalid user logged in.");
        }
    }
    
    public static function GetData($token)
    {
        return JWT::decode(
            $token,
            self::$secret_key,
            self::$encrypt
        )->data;
    }
    
    private static function Aud()
    {
        $aud = '';
        
        if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
            $aud = $_SERVER['HTTP_CLIENT_IP'];
        } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
            $aud = $_SERVER['HTTP_X_FORWARDED_FOR'];
        } else {
            $aud = $_SERVER['REMOTE_ADDR'];
        }
        
        $aud .= @$_SERVER['HTTP_USER_AGENT'];
        $aud .= gethostname();
        
        return sha1($aud);
    }
}

 

Ejemplo de autenticación

En nuestro flujo normal una vez validado nuestro usuario y password llamamos al método SignIn y le pasamos la información que queremos guardar, en nuestro la información del usuario. Luego este nos va a retornar el token asociado.

<?php
$usuario  = 'eduardo';
$password = '123456';
                                                                                                                                                                                                                       if($usuario === if($usuario === 'eduardo' && $password === '123456')
{
    echo Auth::SignIn([
        'id' => 1,
        'name' => 'Eduardo'
    ]);
}

 

Recuperando la data de nuestro usuario guardada en el token

Le pasamos el token generado y este nos retornará la información del usuario.

$token = $_GET['t'];

var_dump(
    Auth::GetData(
        $token
    )
);

 

LEEME

Estoy adjutando el ejemplo práctico para ello van a tener que jugar con la URL para poder hacer funcionar el ejemplo.

  1. Ejecutamos la siguiente ruta: index.php?p=autentica
    Este nos va a generar un TOKEN y copiamos dicho TOKEN para hacer las pruebas necesarias.
  2. Ejecutamos la siguiente ruta: index.php?p=verifica&t={token}
    Reemplazamos {token} por el valor que copiamos en el paso 1, si todo esta bien veremos la información de nuestro usuario que guardamos en el token.

 

Como dije, el uso de TOKEN requiere de mayor conocimiento. Si tienes duda déjame un comentario para responderte lo más pronto posible.

¡Adquiera ya!

  • Código de fuente de Red Social desarrollada en ASP.NET MVC

    Código de fuente de Red Social desarrollada en ASP.NET MVC
  • Software de Venta e Inventario hecho en PHP y Codeigniter

    Software de Venta e Inventario hecho en PHP y Codeigniter
  • Software de Portafolio Profesional hecho en ASP.NET MVC 5 C#

    Software de Portafolio Profesional hecho en ASP.NET MVC 5 C#

Últimas publicaciones

Encuesta

¿Sobre qué te gustaría que se hable más?

Síguenos

Estudia con nosotros y crece profesionalmente

Nuestros cursos han sido hecho en base a lo que demanda el mercado hoy en día.
La experiencia obtenida es la de un ambiente laboral.

Anexsoft
© 2017 Anexsoft, blog y cursos online de TI.