Autenticando uma API em NodeJs com JSON web Tokens - Desenvolvimento de Software - TecnoHub
jonathan Agosto 14, 2020, 3:17pm #1
A autenticação é um ponto importante em qualquer aplicação que tenha sua distribuição baseada em usuários. Pensando nisso, trazemos este tutorial de como criar uma autenticação baseada em tokens para autenticar usuários que acessarem sua API. O módulo que vamos utilizar para trabalhar com os tokens é o jsonwebtoken .
Vamos construir uma mini API que terá a autenticação baseada em WebTokens, então teremos um registro de usuários (Utilizando o MongoDB para armazenarmos os usuários), as rotas que serão liberadas apenas se o usuário estiver autenticado, e o middleware que fará a verificação do token para nós.
Para isso vamos precisar de uma maquina com o NPM, NodeJS instalados e também do aplicativo POSTman , com ele vamos conseguir fazer os testes nas rotas de uma forma mais simples.
Para isso vamos precisar da seguinte estrutura de arquivos:
------------ user.js
No seu arquivo 'package.json' informe um nome para sua aplicação e deixe o 'main' com o nome de seu arquivo server.js
"name": "api-token",
Instalando os pacotes do npm.
No seu console digite " npm install express body-parser morgan mongoose jsonwebtoken --save "
Dessa forma o npm vai baixar os pacotes e já inserir eles nas dependências do nosso projeto, dentro do package.json
900×474 23.6 KB
express É o pacote mais simples para criarmos as rotas do nosso app.
body-parser Com ele conseguimos trabalhar com os dados enviados no body das requisições http que nossas rotas estão recebendo
morgan Com ele para cada requisição que nosso app receber, um log é gerado no nosso console. (Usamos para facilitar a visualização do que está sendo feito)
mongoose É uma biblioteca do Node para MongoDB usada para para modelar os dados da sua aplicação utilizando esquemas.
nodemon Pacote usado para subir sua aplicação com a vantagem de que a cada vez que alterar ou criar um arquivo js ele reinicia automaticamente.
jsonwebtoken Este é o pacote responsável pela geração dos tokens de autenticação.
Criando o modelo dos dados do usuário que será salvo no banco.
No arquivo user.js que fica na pasta /app/models/user.js, faça a seguinte configuração:
// Vamos adicionar nosso pacote do mongoose e criar um objeto com schema do nosso usuário que será salvo no banco.
var usuarioSchema = new mongoose.Schema({
// Agora aqui vamos devolver o Schema do usuário para quer acessar este arquivo
module.exports = mongoose.model('Usuario', usuarioSchema)
Criando o nosso banco utilizando o mLab.
Acesse o site do mLab e siga os próximos passos.
Clique em Create New ao lado de Create from backup .
900×405 168 KB
Depois selecione a opção Single-node , marque o check de Sandbox , de um nome para seu banco e depois clique em Create new MongoDB deployment .
705×937 59.7 KB
Após este passo, selecione o seu banco e adicione um usuário para ele na aba Users clicando no botão Add database user. Note que marquei em vermelho URL do nosso banco, mongodb://< dbuser >:< dbpassword >@ds163377.mlab.com:63377/token-api onde está < dbuser > e < dbpassword > mude para os dados do usuário que você cadastrou. No meu caso ficou da seguinte forma: mongodb://admin:[email protected]:63377/token-api
900×459 127 KB
Arquivo config.js
Agora adicionamos nossa variável 'secret' que será usada para a geração do token e também adicionamos a url do nosso banco.
'secret': 'itsasecret',
'url': 'mongodb://admin:[email protected]:63377/token-api'
// Caso for utilizar o mongoDB localmente
// 'url' : 'mongodb://localhost/projeto-api'
Arquivo server.js
Nele vamos informar todos os pacotes que vamos utilizar, configurar nossa aplicação com as variáveis importantes, conexão com o banco, criar as rotas básicas como a de criação de um usuário de testes e criar as rotas da API que serão dividas da seguinte forma:
- Rota basica -
POST - /cadastrar
Vamos cadastrar o nome e senha que o usuário nos forneceu.
POST - /api/authenticate
Vamos verificar o nome  e senha no nosso banco e liberar um Token para o usuário utilizar, caso o nome e senha estejam corretos. Esta rota não vai precisar de um Token, pois é nela que o usuário vai conseguir ele.
GET - /api
Nela vamos mostrar uma mensagem padrão, nessa rota vamos verificar se o usuário requisitou ela usando o Token.
GET - /api/users
Vamos listar todos os usuários cadastrados, porém apenas se quem requisitar estiver utilizando um Token válido.
Como vai ficar o nosso arquivo server.js
// Vamos referenciar os pacotes que precisamos
var User = require('./app/models/user')
mongoose.connect(config.url) // Conectamos no banco
app.set('superSecret', config.secret) // Variável secret
// Logs das requisições
// Rotas ===========
// rota basica
res.send('Olá, a API está em http://localhost:' + port + '/api')
app.post('/cadastrar', (req, res) => {
// Criamos um novo usuário utilizando o schema que montamos na pasta models
var novoUsuario = new User({
name: req.body.name, // A instrução req.body nos retorna um objeto com os dados que foram enviados através de uma requisição
novoUsuario.save((err) => {
if (err) throw err // Se tiver algum erro na hora de salvar, usamos o throw para retornar uma "exception"
console.log('Usuário cadastrado com sucesso')
}) // Se tudo ocorrer bem, retornamos um json dizendo que deu certo
// Rotas da API
// Utiliza uma instancia do Router para as rotas da API
// Rota de autenticacao de usuário (POST /api/authenticate)
apiRoutes.post('/authenticate', (req, res) => {
}, (err, user) => { // O findOne é como um Select, passando um filtro que é o 'name'
// Verificamos se o usuário existe
message: 'A autenticação falhou, o usuário não foi encontrado :C'
// Verificamos se a senha é correta
if (user.password !== req.body.password) {
message: 'A autenticação falhou, a senha está incorreta :C'
// Se não tiver nenhum erro, então criamos o Token para ele
var token = jwt.sign(user, app.get('superSecret'), {
expiresIn: '1440m'
}) // Aqui dizemos que o Token expira em 1440 minutos (24 hrs)
// Retornamos um json dizendo que deu certo junto com o seu Token
message: 'Aproveite seu token!',
// middleware para validar o Token
apiRoutes.use((req, res, next) => {
// Aqui vamos verificar o header da requisição, os parametros e o corpo da requisição, procurando o token
// Se o token existir
// Verificamos se o token está batendo com a nossa Secret
jwt.verify(token, app.get('superSecret'), (err, decoded) => {
message: 'A autenticação com o token falhou.'
// Se o token estiver válido, então salvamos ele e liberamos o acesso, fazemos o trabalho do porteiro de um prédio aqui.
req.decoded = decoded
// Se quem requisitou não informou o token, devolvemos um erro para ele.
message: 'Nenhum token foi informado.'
// Rota para nos devolver uma mensagem aleatória (GET /api)
apiRoutes.get('/', (req, res) => {
message: 'Bem vindo a API mais dahora no mundo!'
// Rota que retorna todos os usuários cadastrados no banco (GET /api/users)
apiRoutes.get('/users', (req, res) => {
User.find({}, (err, users) => { // O que fizemos aqui foi basicamente um Select na "tabela" de usuários
// Aqui dizemos que as rotas terão o prefixo /api
console.log('Servidor iniciado em http://localhost:' + port)
Para executar utilize no console 'nodemon server.js'
Vamos por partes! ( Rotas da API)
Teste no POSTman
701×448 23.8 KB
715×483 27.8 KB
Autenticação do token.
Testes no POSTman
710×634 61.8 KB
708×470 27.2 KB
Usuário invalido
715×486 27.6 KB
Neste passo vamos montar a proteção das nossas rotas.
Erro (Token inválido)
710×436 25.3 KB
Erro (Token vazio)
703×413 23.3 KB
Recentemente encontrei este tutorial em um site e resolvi traduzir ele e deixar de uma forma mais simples, ele nos da uma boa visão de como proteger nossas rotas utilizando o JSON Web Token, caso queira algum tutorial especifico nos deixe um comentário, valeu pessoal!
Já ia me esquecendo, caso queira verificar o projeto completo baixe o anexo do post, você também pode clonar ele para sua maquina pelo git clone https://github.com/nulldreams/autenticacao-api-jwt.git
https://tsdn.tecnospeed.com.br/files/render/a/W7gaJdtaIFE/m/2Aal0HUq8WfjnTwpp4qU6dY9uyJwEa-PuTA1eqYuddgUgl0wsOBBqsyKrqzHy2AMq8HzIeqITXs