Usando Token Based Authentication (Json Web Token) en ExpressJS

Diego Guevara
4 min readJan 18, 2017

--

Tradicionalmente, el método de autenticación que se ha usado en aplicaciones Web ha sido el método basado en Cookies (Cookies Based Auth), en donde, a través de cookies se mantenía una sesión activa entre el servidor y el cliente.

Cuando usamos Token Based Auth, se utiliza un Token único que se asigna al momento de verificar las credenciales y que se debe enviar por parte del cliente cada vez que se hace una solicitud a un método de un servicio. Este método ha alcanzado grán popularidad actualmente por su enfoque completamente Stateless y por eso es perfecto para el desarrollo de APIs REST.

Beneficios

Cross-domain: permite hacer llamados a un api en otro dominio y mantener la validación de usuarios.

Stateless: Cada llamado es independiente y no se necesita almacenar datos de sesión.

CDN: Permite utilizar un CDN para librerías y utilidades comunes.

Modularidad: Permite la reutilización del api sin importar la plataforma del cliente.

Mobile ready: listo para ser compatible con aplicaciones móviles nativas.

Proceso de autenticación

El proceso se divide principalmente en 2 partes:

  1. Autenticación: En este paso debemos enviar las credenciales del usuario a un servicio REST de Login, el cual validará las credenciales y retornará un Token de Autorización temporal.
  2. Autorización: Por cada llamado a algún otro servicio REST de nuestra aplicación debemos enviar el Token de acceso a través del HEADER de la solicitud, la aplicación podrá capturar el token y verificar su validez y sus permisos para el servicio solicitado.

Instalación y Configuración

Instalación de las librerías a través de NPM

Suponemos que en este punto ya tienes tu aplicación NodeJS configurada con ExpressJS.

Las librerías que necesitamos las instalamos a través de NPM;

$ npm install express-jwt jsonwebtoken --save

Inclusión de librerías en nuestra aplicación

Lo primero es incluir mediante require las librerías en nuestra aplicación. Esto debe hacerse en el archivo app.js ya que es donde se configuran las rutas de acceso a los servicios.

// librerias para JWT (Json Web Token)
var expressJwt = require('express-jwt');

Configuración de las librerías

Luego incluimos el siguiente código en el mismo archivo app.js antes de la configuración de rutas.

app.use( 
'/api/v1', // Ruta raíz de los servicios del API
expressJwt(
{
secret : 'hash o frase secreta semilla de encripcion'
}
)
.unless( { path: ['/api/v1/login']} ) // Ruta del servicio de login
);

Como se ve en el diagrama del proceso, debemos contar con un servicio REST de login o autenticación, el cual se encarga de recibir y validar las credenciales de usuario y retornar el Token de autorización.

Al configurar nuestras librerías de JsonWebToken debemos indicar cual es la ruta de nuestos servicios REST a proteger y cual es la ruta del servicio que usaremos como Login o autenticación.

En el caso de nuestro ejemplo, la ruta de todos nuestros servicios REST es /api/v1.

y la ruta de nuestro servicio de login es /api/v1/login

En la configuración de JWT, usando la propiedad unless podemos indicarle a la librería todas las rutas que queremos excluir de la proteccion.

Por último, debemos escojer una frase secreta que será usada como semilla para la encripción del token.

Esta frase por lo general es una cadena de caracteres larga preferiblemente con números, letras y caracteres especiales para aumentar la seguridad de nuestro token.

Servicio de validación de acceso y generación de token

En el servicio de login o autenticación, es donde debemos generar el token de autorización una vez hayamos validado las credenciales de usuario.

En el ejemplo, tenemos nuestro servicio llamado /api/v1/login que mediante el uso del método POST capturará las credenciales de usuario y generará el Token:

Primero debemos incluir la librería de JWT:

var jwt = require( 'jsonwebtoken' );

Luego de validar las credenciales de usuario incluimos el siguiente código que se encarga de generar un string con el Token de autorización.

var token = jwt.sign( 
data_, // objeto json con los datos que se almacenan en el token
'hash o frase secreta semilla de encripcion',
{
expiresInMinutes: 60*5 // tiempo máximo de validez del token
} );

Para ver un ejemplo más completo de login:

/**
* Validar credenciales de autenticacion de usuario
* @method
* @param {object} req request
* @param {object} res response
* @param {object} next
* @return {json} resultado de validacion
*/
router.post('/', function(req, res, next) {
AuthCore.authenticateUser(
req.body.user_email,
req.body.user_password,
req.body.user_type,
function( err_, data_ ) {
if( err_ ){
res.status( 401 ).json( { message : 'Invalid Credentials', content: null } );
return;
}
// Generamos el token de autorizacion
var token = jwt.sign( data_, 'hash o frase secreta semilla de encripcion', { expiresInMinutes: 60*5 } );
res.status( 200 ).json( { message : null, content: token } );
});
});

En resumen, se validan las credenciales de usuario, si no son correctas enviamos un error 401 indicando que las credenciales son invalidas.

En caso de que las credenciales son validas, llamamos al método jwt.sign con los datos que queremos incluir en el token, la frase secreta y el tiempo de máximo de vida del token y luego retornamos este token al cliente.

Y con esto ya tenemos nuesto API sobre ExpressJS protegido con un Json Web Token.

--

--

Diego Guevara

I'm a software engineer, JS Dev, creator of Grabitt.co, entrepreneur, photographer 📷 and House music deejay 🎧