Sigueme en Facebook Sigueme en Twitter Sigueme en Instagram Sigueme en Youtube
JC Mouse Bolivia
Index / Proyectos / JSON Web Tokens: Teoría y práctica

JSON Web Tokens: Teoría y práctica

Autor jc mouse jueves, agosto 17, 2017

En este post aprenderemos lo que es un JSON Web Token, como crear nuestro propio token de acceso y como usarlo en un Servicio Web.

Necesitamos:

Nivel: Intermedio – Avanzado

Tiempo 30 minutos

¿Que es JSON Web Token?

JSON Web Token (JWT) es un estándar abierto (RFC 7519) que define una forma compacta y autónoma para transmitir de forma segura la información entre las partes como un objeto JSON. Esta información puede ser verificada y confiable porque está firmada digitalmente. Los JWT se pueden firmar usando una llave secreta (con el algoritmo HMAC) o claves públicas/privadas usando RSA.

La Autenticación es el escenario más común para usar JWT, un vez que el usuario a iniciado sesión, cada solicitud posterior incluirá el JWT, permitiendole al usuario acceder a recursos que requieran de ciertos privilegios

ejemplo json token

Estructura del Json Web Tokens

Un JWT es una cadena que consta de tres partes separados por un punto (.), por ejemplo:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

Estas partes del JWT son, el Header (encabezado), el Payload (Carga Util) y la Signature (Firma).

A continuación iremos explicando y construyendo nuestro propio JWT utilizando algunas herramientas online, no usaremos ningún lenguaje de programación en su construcción, aunque en la practica sea cual fuere el lenguaje que utilices (PHP, Java, NET, etc) debes implementar los métodos necesarios tanto para la construcción como la validación del JSON Web Token.

Header

El encabezado consta por lo general de dos partes, el Tipo de token (JWT) y el algoritmo utilizado para la codificación (HS256), el algoritmo puede ser cualquier otro.

{
  "alg": "HS256",
  "typ": "JWT"
}

Este JSON se codifica usando Base64 sin espacio ni saltos de linea, utilizando la herramientas Base64 Decode and Encode convertimos el JSON de arriba y obtenemos:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

Reservamos esta cadena por el momento

PayLoad

El Payload o Carga Útil, contiene información relevante del usuario entre otros metadatos, estos se almacenan en los JWT Claims que pueden ser de tres tipos, reservadas, publicas y privadas.

  • Reservadas: Predefinidas por JWT, por ejemplo iss (emisor), exp (Tiempo de duración del token), iat (emitido en)
  • Publicas: Creadas por el programador (osea usted) 🙂 , por ejemplo «lvl»:1 (Nivel de acceso) o «adm»:true (administrador), pero también pueden ser una URI «http://ejemplo.com/is_admin»:true.
  • Privadas: Igualmente creadas por el programador, pero esta se acuerdan entre partes que utilizaran este JWT.

Para nuestro ejemplo el JSON Payload sera el siguiente:

{
  "usr": "mouse",
  "lvl": 0,
  "exp": 1596672000
}

Explicación del JSON Payload:

Definimos el usuario que hará uso del token (mouse), el nivel que tiene este usuario (ej.: 0:superamin, 1:admin 2:cliente, 3:visitante, etc, etc), con exp indicamos el tiempo que tendrá validez el token (por lo general 1 hora, 30 minutos, etc), este tiempo lo indicamos en formato UNIX (1596672000 equivale a 06/08/2020 6 de agosto de 2020, usamos esta fecha para que les salga lo mismo al usar las herramientas de conversión). Podemos usar más o menos metadatos, eso depende de cada uno.

Nuevamente usando la herramienta on-line de Base64, codificamos y obtenemos:

eyJ1c3IiOiJtb3VzZSIsImx2bCI6MCwiZXhwIjoxNTk2NjcyMDAwfQ

Signature

La firma, es la tercera y ultima parte del del JSON Web Token, esta firma esta formado por las dos componentes anteriores (header y payload) cifrados en base64 usando un algoritmo como SHA-256 con una clave secreta almacenada en nuestro back-end. De esta forma el resultado nos servirá como HASH para comprobar que los metadatos no fueron alterados.

Para nuestro ejemplo  header.payload

es decir:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c3IiOiJtb3VzZSIsImx2bCI6MCwiZXhwIjoxNTk2NjcyMDAwfQ

Utilizamos la herramienta de conversión SHA 256 y nuestra palabra secreta sera «bolivia» 🙂 obtenemos:

hash base64

base64: 9u7gyg2VR07Gjpe2uhpxOvLL9DmJcrhWnoBk8YxKhQk

Y finalmente concatenamos cada parte separados con un punto header.payload.signature y nuestro JSON Web Tokens es:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c3IiOiJtb3VzZSIsImx2bCI6MCwiZXhwIjoxNTk2NjcyMDAwfQ.9u7gyg2VR07Gjpe2uhpxOvLL9DmJcrhWnoBk8YxKhQk

¿como comprobamos que generamos correctamente el token?

La web de JWT (https://jwt.io/) nos facilita una herramienta para comprobar la validez del token para HS256 y RS256. Debemos pegar nuestro JWT y la palabra secreta, si el token es correcto tendremos:

validate token

Usando JSON Web Token

Este tutorial no se trata sobre programación de un REST API, por lo que no profundizaremos en el tema y nos limitaremos a presentar un REST de ejemplo sencillo tomándonos ciertas libertades en lo que respecta a la programación de un API en PHP 🙂

En tu servidor crea una carpeta con el nombre de «demoapi«, en esa carpeta crea dos archivos, login.php y alumnos.php, el primero es para autenticar al usuario y el segundo para realizar una solicitud cualquiera al API usando el JWT.

Archivo: login.php

<?php
if($_POST){//autenticacion de usuario
    //obtiene datos de usuario
    $user = $_POST['user'];
    $pass = $_POST['pass'];    
    //comprueba dato de usuario
    if($user=='mouse' && $pass=='123'){//base de datos
        /**
         * Genera el JSON Web Token
         * 
         * Tus funciones base64 hs256 van aqui
         */        
        $jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c3IiOiJtb3VzZSIsImx2bCI6MCwiZXhwIjoxNTk2NjcyMDAwfQ.9u7gyg2VR07Gjpe2uhpxOvLL9DmJcrhWnoBk8YxKhQk";
        
        /**
         * Responde al usuario incluyendo el JWT en el encabezado
         */
        http_response_code(200);//respuesta HTTP        
        header('Content-type: application/json;charset=utf-8');
        header("Authorization: " . $user ." ". $jwt); //JSON Web Token
        echo json_encode(array("Saludo"=>"Bienvenido " . $user));//respuesta en JSON
    }else{//los datos son incorrectos
        http_response_code(401);
        echo json_encode(array("Error"=>"Acceso no autorizado"));
    }
}

Archivo: alumnos.php

<?php
//obtiene headers
$headers = getallheaders();
if(isset($headers['Authorization'])){//existe JWT
    //comprueba validez del JWT
    $jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c3IiOiJtb3VzZSIsImx2bCI6MCwiZXhwIjoxNTk2NjcyMDAwfQ.9u7gyg2VR07Gjpe2uhpxOvLL9DmJcrhWnoBk8YxKhQk";
    /**
     * para este ejemplo realizamos una simple comparacion, en un caso real, 
     * debemos decodificar el token, y con la palabra secreta "bolivia" comprobar el HASH para
     * verificar si el JWT a sido alterado o no
     * 
     * despues comprabar los metados
     * - si el tiempo de vida del token esta vigente o ya expirado
     * - si el usuario que realiza la solicitud tiene los permisos necesarios
     * - etc
     * - etc
     * 
     * y actuar en consecuencia
     */
    if($headers['Authorization']==$jwt){
        http_response_code(200);
        //encabezado con JWT
        header('Content-type: application/json;charset=utf-8');
        /**
         * en este ejemplo retornamos el mismo JWT, pero en un caso real 
         * debemos generar un nuevo token con la fecha de expiracion actualizada
         */        
        header("Authorization: mouse ". $jwt); //JSON Web Token
        //retorna JSON solicitado
        echo json_encode(array("nombre"=>"Aquiles Brinco","edad"=>99,"correo"=>"correo123@mail.com"));
    }else{//no existe "Authorization"
        http_response_code(401);
        echo json_encode(array("Error"=>"Acceso no autorizado"));
    }    
}else{//No existe JWT 
    http_response_code(401);
    echo json_encode(array("Error"=>"Acceso no autorizado"));
}

Autenticacion de Usuario

Abre Insomnia y crea una nueva solicitud POST con parámetros user: mouse y pass:123

request

Preciosa SEND y obtendrás como resultado el siguiente JSON:

response 200

clic en la pestala Header, podrás observar que nuestro REST a parte de responder con JSON, a incluido en el encabezado el token de acceso

autorizacion json

Este JWT debemos guardar en nuestro cliente y enviarlo en cada solicitud que realicemos.

Solicitud con JWT

Crea una nueva solicitud GET, en la pestaña Header, agrega el campo «Authorization» y en su value, agrega el JWT que recibimos en la autenticación, es decir:

get solicitud

Ahora presiona SEND y obtendrás el JSON de respuesta, y en el header el JWT actualizado

respuesta http

Realiza la misma solicitud, pero esta vez desactiva el campo «Authorization» y obtendrás:

no autorizado 401

Lecturas de interés (ingles):

https://tools.ietf.org/html/rfc7519

https://jwt.io/

https://jwt.io/introduction/

enjoy!!!

Tags

Si te ha gustado podrías compartirlo o dejar un comentario. ¡Muchas gracias!
Autor: JC Mouse

Yo soy yo :) JC Mouse, Soy orgullosamente boliviano soy fundador y CEO de la web jc-Mouse.net uno de las pocas web en emprendimiento y tecnología en Bolivia.

Toda la información que encuentres en este sitio es y sera completamente gratis siempre, puedes copiar, descargar y re-publicar si así lo deseas en otros blogs o sitios web, solo te pido a cambio que dejes una referencia a esta web. Esto nos ayuda a crecer y seguir aportando. Bye

Enjoy! :)

También Te Podría Interesar

Conexión a base de datos Oracle con Laravel

Conexión a base de datos Oracle con Laravel

En esta ocasión aprenderemos a conectaros con una base de datos Oracle desde Laravel. Es un tutorial sencillo y cortito,...

Procedimientos Almacenados: Parámetros IN

Procedimientos Almacenados: Parámetros IN

Una procedimiento almacenado es un conjunto de sentencias de SQL que se pueden almacenar en el servidor, de esta forma n...

Biblioteca Matemática avanzada para java

Biblioteca Matemática avanzada para java

Java cuenta con la clase java.lang.Math  la cual contiene métodos para realizar operaciones numéricas básicas como las f...

Subir imagen a un servidor web con REST/JSON

Subir imagen a un servidor web con REST/JSON

En este tutorial crearemos una sencilla aplicación para android que nos permitirá subir una imagen a un servidor web. La...

Mapas con HTML5 – Funciones de pintado – Parte 5

Mapas con HTML5 – Funciones de pintado – Parte 5

En esta penúltima parte, declaramos las funciones que nos permitirán pintar los shapes en el canvas, vamos al grano que...

«Hola Bolivia» mi primera aplicación android

«Hola Bolivia» mi primera aplicación android

Cuando se inicia el aprendizaje de un lenguaje de programación, nunca debe faltar el clásico «Hola Mundo» 🙂 en Android n...

1 comentario en “JSON Web Tokens: Teoría y práctica”

  1. Elisa dice:

    Excelente! tu post me a encantado y ayudado muchiiiiisimo! Estoy muy agradecida. EG de Vzla

Los comentarios estan cerrados

Comparte lo que sabes

Categorias

Últimas entradas

El gigante tecnologico Google a puesto un bonito Doodle en su buscador que esta fascinando a sus millones de usuarios qu...

WhatsApp anuncio a través de su blog que ya se encuentra disponible la función de envío de fotos y videos TEMPORALES, es...

Muchas de las innovaciones computacionales de la NASA se desarrollaron para ayudar a explorar el espacio, pero ahora la...

TikTok es una plataforma de microvideos muy popular entre los jóvenes el cual cuenta ya con millones de videos cortps de...

Herramientas

Generador de Enlaces a Whatsapp