Home » Insights » Começando uma API REST com Node.JS Parte 3

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

Índice

    Faala galera, demorei mas voltei com a parte 3 do artigo de como fazer uma API com nodeJs!

    Mas antes caso não tenham visto a part 1 e part2, da um conferida.

    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 tem 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 alterei 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 estou 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 me 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 minha 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 🙂  – Parte 4 aqui


    Publicado

    em

    por