← Back to Lessons
Edit on Github

Intro To JWT with NodeJS

NodeJS y JWT

JSON Web Token es un estándar abierto basado en JSON propuesto por IETF para la creación de tokens de acceso que permiten la propagación de identidad y privilegios o claims en inglés

Contruir una API

En este caso configuramos una api muy simple en la cual se analizara la forma de integrar jwt

Iniciar nuestro proyecto

$ npm init -y

Instalar las dependencias necesarias

$ npm i --save express jsonwebtoken

Creamos un archivo index.js y agregamos el siguiente contenido:

1const express = require('express'); 2const jwt = require('jsonwebtoken'); 3const PORT = process.env.PORT || 3000; 4const SECRET_KEY = process.env.SECRET_KEY || 'secret-key'; 5const app = express(); 6 7app.use(express.json()); 8app.use(express.urlencoded({ extended: false })); 9 10app.get('/', (req, res) => { 11 res.send('API REST NodeJS'); 12}) 13 14app.listen(PORT, () => console.log(`Server running at http://localhost:${PORT}`));

Iniciamos nuestro servidor

$ node index.js

Agregar una ruta para nuestra autenticación

1 2app.post('/token', (req, res) => { 3 const { username, password } = req.body; 4 if(!(username && password)) return res.status(400).json({ msg: 'Username/Password are required!'}) 5 6 if(username === 'admin' && password === 'admin'){ 7 const payload = { 8 username: username, 9 } 10 11 const token = jwt.sign(payload, SECRET_KEY, { expiresIn: 1440 }); 12 13 return res.status(200).json({ 14 token: token 15 }) 16 } else { 17 return res.status(401).json({ msg: 'Username/password are incorrect!'}); 18 } 19})

Debemos obtener una respuesta similar a esta

1{ 2 "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiaWF0IjoxNjYyNzYyOTU2LCJleHAiOjE2NjI3NjQzOTZ9.NH9johw1YWdhW5RQTCWpFBNNks7gHauUPDbrVxUyaMA" 3}

Ahora debemos crear un middleware que se encargara de validar el token al momento de acceder a un endpoint privado:

1... 2const auth = require('express').Router(); 3 4auth.use((req, res, next) => { 5 const token = req.headers['x-access-token']; 6 7 if(token){ 8 jwt.verify(token, SECRET_KEY, (err, decoded) => { 9 if(err) return res.json({ msg: 'Token is invalid!'}) 10 req.decoded = decoded; 11 next(); 12 }) 13 }else{ 14 return res.status(400).json({ msg: 'Token is missing!'}); 15 } 16});

Ahora agregamos una ruta privada y utilizamos nuestro middleware que valida si viene el token en el request.

1 2app.get('/datos-privados', auth, (req, res) => { 3 const tasks = [ 4 { task: 'Task 1', done: false }, 5 { task: 'Task 2', done: false }, 6 { task: 'Task 3', done: true }, 7 { task: 'Task 4', done: false }, 8 ] 9 10 return res.status(200).json(tasks); 11})

Nuestro archivo index.js deberia contener lo siguiente:

1const express = require('express'); 2const jwt = require('jsonwebtoken'); 3const auth = require('express').Router(); 4const PORT = process.env.PORT || 3000; 5const SECRET_KEY = process.env.SECRET_KEY || 'secret-key'; 6const app = express(); 7 8app.use(express.json()); 9app.use(express.urlencoded({ extended: false })); 10 11app.get('/', (req, res) => { 12 res.send('API REST NodeJS'); 13}) 14 15app.listen(PORT, () => console.log(`Server running at http://localhost:${PORT}`)); 16 17app.post('/token', (req, res) => { 18 const { username, password } = req.body; 19 if(!(username && password)) return res.status(400).json({ msg: 'Username/Password are required!'}) 20 21 if(username === 'admin' && password === 'admin'){ 22 const payload = { 23 username: username, 24 } 25 26 const token = jwt.sign(payload, SECRET_KEY, { expiresIn: 1440 }); 27 28 return res.status(200).json({ 29 token: token 30 }) 31 } else { 32 return res.status(401).json({ msg: 'Username/password are incorrect!'}); 33 } 34}) 35 36auth.use((req, res, next) => { 37 const token = req.headers['x-access-token']; 38 39 if(token){ 40 jwt.verify(token, SECRET_KEY, (err, decoded) => { 41 if(err) return res.status(403).json({ msg: 'Token is invalid!'}) 42 req.decoded = decoded; 43 next(); 44 }) 45 }else{ 46 return res.status(400).json({ msg: 'Token is missing!'}); 47 } 48}); 49 50app.get('/datos-privados', auth, (req, res) => { 51 const tasks = [ 52 { task: 'Task 1', done: false }, 53 { task: 'Task 2', done: false }, 54 { task: 'Task 3', done: true }, 55 { task: 'Task 4', done: false }, 56 ] 57 58 return res.status(200).json(tasks); 59})