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); };
npm install jsonwebtoken
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(); }); }
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.' }) } };
Adicionamos uma rota para o login: AuthRoute.js
const AuthController = require('../Controllers/AuthController'); module.exports = (app) => { app.post('/login', AuthController.login); }
E puxamos ela no Routes/index.js
const UsuarioRoute = require('./UsuarioRoute'); const AuthRoute = require('./AuthRoute'); module.exports = (app) => { UsuarioRoute(app); AuthRoute(app); }
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); }
Pronto! Bem simples, não? Vamos testar!
Se tentarmos acessar nossa rota de get /usuarios vamos receber a seguinte mensagem:
Muito bom! Agora vamos fazer o login: O usuário que temos é “Mariana” e a senha “123456”.
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.
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 🙂
Top comments (0)