menu

SHARKLABS

JSON Web Token e NodeJS: É mais fácil do que você pensa

/
/
JSON Web Token e NodeJS: É mais fácil do que você pensa
bookmark Node.js, REST-API access_time

Esqueça as sessões

Tradicionalmente na Web as autenticações são feitas por sessões, mas isso vem mudando com o conceito de Stateless aplicado no uso das REST API.

Neste conceito toda requisição deve conter todos os dados necessários para processamento no servidor. Desta forma é fácil ter softwares altamente escaláveis.

Se quer entender um pouco mais sobre isso, leia este artigo da Caelum que fala sobre as boas práticas aplicadas em REST API.

JWT: A melhora alternativa

Existem vários padrões para autenticar as REST API, mas o meu preferido é o JSON Web Token. É um padrão seguro, simples e fácil de implementar.

O JWT é formado por três partes:

  • Header: Contem o tipo do token e o algoritmo de criptografia.
  • Payload: Dados do usuário, emissor do token, data de criação e expiração, etc...
  • Signature: Header e Payload criptografado com uma chave secreta.

Simples não é? Se você quer mais detalhes leia este artigo publicado pelo Tableless.

Show me code

Chega de introdução e vamos ao que interessa.

Eu criei um exemplo de REST API com NodeJS usando JSON Web Token como método de autenticação.

As bibliotecas que eu utilizei são as seguintes:

  • express: Funcionando como servidor HTTP e roteador.
  • jsonwebtoken: Responsável pela geração do Token.
  • express-jwt: Midleware para Express capaz de validar um token durante uma requisição HTTP.

O código ficou desta maneira:

let secretKey = 'my-secret-key';

let app = require('express')();
let bodyParser = require('body-parser');

let jwt = require('jsonwebtoken');
let jwtMiddleware = require('express-jwt')({
  secret: 'my-secret-key',
});

app.use(bodyParser.urlencoded({ extended: false }));

app.use(bodyParser.json());

app.listen(3000, function () {
  console.log('Example app listening on port 3000!');
});

app.post('/login', (req, res, next) => {
  // DANGER: Don't use this IF in production software
  if (req.body.user == 'john' && req.body.password == '123456') {
    res.setHeader('Content-Type', 'application/json');
    res.send({ token: tokenGenerate() });
  } else {
    res.sendStatus(401);
  }
});

app.get('/cars', jwtMiddleware, (req, res, next) => {
  res.setHeader('Content-Type', 'application/json');
  res.send([
    { id: 1, name: 'Ferrari' },
    { id: 2, name: 'Mercedes' },
  ]);
});

function tokenGenerate() {
  let tomorow = new Date();
  tomorow.setDate(tomorow.getDate() + 1);
  return jwt.sign({ exp: tomorow.getTime() }, secretKey);
}

Essa é a implementação do servidor. O código de um software cliente ficaria da seguinte maneira:

async function main() {
  try {
    let token = (
      await axios.post('http://localhost:3000/login', {
        user: 'john',
        password: '123456',
      })
    ).data.token;

    let res = await axios.get('http://localhost:3000/cars', {
      headers: {
        Authorization: 'Bearer ' + token,
      },
    });
    console.log(res.data);
  } catch (e) {
    console.log(e.response.statusText);
  }
}

Como vocês podem ver é super fácil usar JSON Web Token com NodeJS. O código completo está disponível neste link.

Dúvidas ou sugestões é só entrar em contato. Abraço.

Autor
"Any fool can write code that a computer can understand. Good programmers write code that humans can understand." Martin Fowler