Back-End

30 out, 2018

Node.js: criando um token JWT sem plugin

Publicidade

Em um dos meus artigos anteriores eu fiz uma breve introdução ao JWT (JSON Web Token), utilizando o Node.js. Caso tenha interesse em ler esse artigo, segue o link:

Hoje mostrarei como criar um token JWT utilizando Node.js, sem a necessidade de um plugin de terceiros. Somente fazendo uma introdução rápida, um token JWT é composto por: Header, Payload e Signature.

Para esse artigo ficar mais dinâmico, eu irei apresentar cada uma dessas partes, junto com um trecho de código que utilizaremos para gerar o nosso token.

Header

Nessa parte nós devemos informar o tipo e o algoritmo que utilizaremos. O tipo será JWT, e o algoritmo pode ser HMAC SHA256 ou RSA. Para esse artigo utilizaremos o SHA256. Abaixo, você tem um trecho de código demonstrando essa etapa:

let header = {
    "typ": "JWT",
    "alg": "HS256"
}

header = JSON.stringify(header);
header = Buffer.from(header).toString('base64');

Resultado no console.log(header):

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9

Essa é a primeira parte do nosso token.

Payload

Nesta parte devemos passar os dados que devem retornar no token. O JWT tem algumas palavras reservadas que não são obrigatórias, mas “no meu ponto de vista” é legal utilizarmos para ter um padrão. Abaixo você pode ver algumas dessas palavras:

  • “iss” (Issuer): origem do token
  • “iat” (issueAt): timestamp de quando o token foi gerado
  • “exp” (Expiration): timestamp de quando o token expira
  • “sub” (Subject): entidade a quem o token pertence, normalmente o ID do usuário

Seguindo com a parte do nosso código, abaixo você tem um exemplo de preenchimento do payload.

let payload = [
    iss = 'omundoedos.net',
    iat = new Date().toLocaleString(),
    exp = new Date().setMinutes(60).toLocaleString(),
    acl = ['coordenador', 'participante'],
    username = 'Thiago Adriano',
    email = 'tadriano.net@gmail.com'
];

payload = JSON.stringify(payload);
payload = Buffer.from(payload).toString('base64');

Resultado no console.log(header.payload).

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.WyJvbXVuZG9lZG9zLm5ldCIsIjIwMTgtMTAtMjUgMTY6NDY6MzYiLCIxLDU0MCw0OTcsNjM2LDA4NiIsWyJjb29yZGVuYWRvciIsInBhcnRpY2lwYW50ZSJdLCJUaGlhZ28gQWRyaWFubyIsInRhZHJpYW5vLm5ldEBnbWFpbC5jb20iXQ==

Note que eu estou concatenando o header e o payload com um ponto. O JWT concatena as três partes dessa forma.

Signature

A assinatura é a terceira parte do token JWT. Ela é composta por: Header + Payload + uma senha definido para nossa aplicação, criptografadas pelo algoritmo que definimos no header. Abaixo você tem um trecho de código demonstrando essa parte.

let key = '.net-sp-ness';
let signature = crypto.createHmac('sha256', key)
    .update(header + "." + payload)
    .digest('base64');

signature = Buffer.from(signature).toString('base64');

Resultado no console.log(SHA256(header.payload + senha)).

OWlWY24ydmtOSEE4Y0U5YWU3VGZlVGI1U0FISUdtZ0ZSYmZDK3E4dk5UMD0=

Agora juntando essas três partes nós temos o nosso token:

let token = header + "." + payload + "." + signature;

Resultado no console.log(token);:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.WyJvbXVuZG9lZG9zLm5ldCIsIjIwMTgtMTAtMjUgMTc6MDI6MjIiLCIxLDU0MCw1MDEsMjIyLDMxMiIsWyJjb29yZGVuYWRvciIsInBhcnRpY2lwYW50ZSJdLCJUaGlhZ28gQWRyaWFubyIsInRhZHJpYW5vLm5ldEBnbWFpbC5jb20iXQ==.QlUxR2kyRG5NbCtzKzVUQm5vTkF0dGEvaEhaTTNsd1ZJbEhlTjhIOFNJRT0=

Para finalizar vamos validar o nosso token no site oficial do JWT. Abaixo você tem uma imagem demonstrando o resultado dessa validação:

Validando token JWT

Note que quando eu colei o token ele apresentou os mesmos dados que nós configuramos nos passos anteriores. Em seguida eu coloquei a key que definimos na assinatura e ele validou o nosso token.

Segue abaixo a versão final do código apresentado neste artigo:

var crypto = require('crypto');


let header = {
    "typ": "JWT",
    "alg": "HS256"
}

header = JSON.stringify(header);
header = Buffer.from(header).toString('base64');

let payload = [
    iss = 'omundoedos.net',
    iat = new Date().toLocaleString(),
    exp = new Date().setMinutes(60).toLocaleString(),
    acl = ['coordenador', 'participante'],
    username = 'Thiago Adriano',
    email = 'tadriano.net@gmail.com'
];

payload = JSON.stringify(payload);
payload = Buffer.from(payload).toString('base64');

let key = '.net-sp-ness';
let signature = crypto.createHmac('sha256', key)
    .update(header + "." + payload)
    .digest('base64');

signature = Buffer.from(signature).toString('base64');

let token = header + "." + payload + "." + signature;

console.log(token);

Bom, o intuito desse artigo era demonstrar como podemos criar um token sem a necessidade de um plugin de terceiros. Espero que tenham gostado e até um próximo artigo, pessoal!