Começando uma API REST com Node.JS #3

kodusprof

Kodus

Posted on August 12, 2022

Começando uma API REST com Node.JS #3

Nossa API já está acessando o banco de dados mongo e agora vamos implementar autenticação JWT para adicionarmos um passo de segurança.

Esse tipo de autenticação é muito comum e é usada para que apenas pessoas autorizadas acessem nossos métodos da API.

O que é o JWT? (JSON Web Tokens)

JWT é uma string codificada que será usada como chave para concluir uma requisição à nossa API.

Toda requisição feita para nossa API o token será validado, permitindo ou não que a transação seja concluída com sucesso.

Esse token é formado por alguns dados criptografados e uma chave privada, que será usada para validar.

Não é indicado que se salve dados sensíveis nesse token, por mais que ele seja criptografado, é possível reverter essa criptografia e assim ler os dados ali contidos.

Leia mais sobre JWT aqui.

Implementando autenticação JWT

Como nossos usuários não têm senha no banco, vamos começar por isso e adicionar uma senha para eles.
Para facilitar, essa é a senha 123456 criptografada: 16fd10090c85fadf1e2413980214b135fafa0169ded1939004ecc4e17dc31b77
Vamos dar um update em nossos usuários e adicionar o campo senha.

Não se esqueçam de atualizar a model de usuário com esse novo campo!

Também alteramos o método de criar usuário, para criar com a senha criptografada:

const crypto = require('crypto');
const secret = 'minhastringdeseguranca101010';

exports.post = async (req, res, next) => {
   const hash = crypto.createHmac('sha256', secret)
       .update(req.body.senha)
       .digest('hex');
   const usuario = await UsuarioModel.create({
       ...req.body,
       senha: hash
   });
   res.status(200).send(usuario);
};
Enter fullscreen mode Exit fullscreen mode
npm install jsonwebtoken
Enter fullscreen mode Exit fullscreen mode

Criaremos uma pasta em src, chamada Middleware, e dentro dela um arquivo Auth.js

const jwt = require('jsonwebtoken');
const secret = 'minhastringdeseguranca101010';

exports.auth = (req, res, next) => {
 const token = req.headers['authorization'];
 if (!token) return res.status(401).send({ auth: false, message: 'Essa rota requer autenticação.' });
  jwt.verify(token, secret, function(err, decoded) {
   if (err) return res.status(500).send({ auth: false, message: 'Token não autorizado.' });

   req.currentUser = decoded.userId;
   next();
 });
}
Enter fullscreen mode Exit fullscreen mode

Nesse método, vamos pegar o valor de authorization do header e validar ele com a biblioteca do JWT.

Criamos também um controller para fazer o login, AuthController.js

Notem que estamos utilizando uma lib chamada crypto, ela vem junto com o node, não precisa de instalação.

const UsuarioModel = require('../Models/Usuario');
const crypto = require('crypto');
const jwt = require('jsonwebtoken');
const secret = 'minhastringdeseguranca101010';

exports.login = async (req, res, next) => {
   const { senha, nome } = req.body;
   const hash = crypto.createHmac('sha256', secret)
       .update(senha)
       .digest('hex');

   const usuario = await UsuarioModel.findOne({ nome, senha: hash });
   if (usuario) {
       const token = jwt.sign({ userId: usuario._id }, secret);
       res.send({auth: true, token})
   } else {
       res.status(401).send({ auth: false, error: 'Nome ou senha inválidos.' })
   }
};
Enter fullscreen mode Exit fullscreen mode

Adicionamos uma rota para o login: AuthRoute.js

const AuthController = require('../Controllers/AuthController');

module.exports = (app) => {
   app.post('/login', AuthController.login);
}
Enter fullscreen mode Exit fullscreen mode

E puxamos ela no Routes/index.js

const UsuarioRoute = require('./UsuarioRoute');
const AuthRoute = require('./AuthRoute');

module.exports = (app) => {
   UsuarioRoute(app);
   AuthRoute(app);
}
Enter fullscreen mode Exit fullscreen mode

Precisamos alterar nosso arquivo de rotas do usuário para adicionar o middleware que criamos logo acima:

const UsuarioController = require('../Controllers/UsuarioController');
const auth = require('../Middleware/Auth').auth;

module.exports = (app) => {
   app.post('/usuario', auth, UsuarioController.post);
   app.put('/usuario/:id', auth, UsuarioController.put);
   app.delete('/usuario/:id', auth, UsuarioController.delete);
   app.get('/usuarios', auth, UsuarioController.get);
   app.get('/usuario/:id', auth, UsuarioController.getById);
}
Enter fullscreen mode Exit fullscreen mode

Pronto! Bem simples, não? Vamos testar!

Se tentarmos acessar nossa rota de get /usuarios vamos receber a seguinte mensagem:
Resposta do GET sem autenticação
Muito bom! Agora vamos fazer o login: O usuário que temos é “Mariana” e a senha “123456”.
Resposta do GET com autenticação
Veja que retornou o token, é isso que vamos usar para fazer as próximas requisições agora.

Voltando pra requisição em usuários, vamos adicionar um parâmetro no header: Authorization, com o valor do token que recebemos quando fizemos o login.
JSON de retorno
Veja que agora ele retorna os dados, completando a requisição.

E assim implementamos com sucesso um esquema de autenticação em nossa API!

*Para uma melhor segurança, o ideal é usar um arquivo .env para salvar o valor da nossa variável secret

Até um próximo artigo 🙂


💖 💪 🙅 🚩
kodusprof
Kodus

Posted on August 12, 2022

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related

Começando uma API REST com Node.JS #3
braziliandevs Começando uma API REST com Node.JS #3

August 12, 2022