1 / 13
Modulo 6 / Back-End com Node.js

Autenticação com JWT

JSON Web Tokens, bcrypt e proteção de rotas.

school Aula 30 schedule 2 horas

Conceito

Autenticação vs Autorização

person Autenticação

Quem é você?

  • Verifica a identidade do usuário
  • Login com email e senha
  • OAuth (Google, GitHub, etc.)

shield Autorização

O que você pode fazer?

  • Define permissões de acesso
  • Admin vs usuário comum
  • Controle por rota/recurso
Login (autenticação) Token gerado Acesso permitido? (autorização)

Abordagens

Sessão vs Token

cookie Sessão (Cookie)

  • Servidor guarda o estado do login
  • Cookie com session ID enviado ao navegador
  • Bom para apps com servidor MVC
  • Difícil escalar (requer shared session storage)

token Token (JWT) ⭐

  • Servidor NÃO guarda estado (stateless)
  • Token enviado no header da requisição
  • Ideal para APIs REST e SPAs
  • Escala facilmente

JWT

Anatomia do token

eyJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOiIxMjMiLCJlbWFpbCI6ImFuYUBlbWFpbC5jb20ifQ.SflKxwRJSMeKKF2QT4fwpM

Header

{ "alg": "HS256", "typ": "JWT" }

Payload (dados)

{ "userId": "123", "email": "ana@email", "iat": 1700000000, "exp": 1700086400 }

Signature

Garante que o token não foi alterado. Usa a secret key do servidor para validar.

Segurança

Hash de senhas com bcrypt

dangerous NUNCA salve senha em texto puro

❌ senha: "minhasenha123"
✅ hash: "$2b$10$N9qo8uLO..."

O hash é irreversível: não dá para descobrir a senha original a partir dele.

code Usando bcrypt

$ npm install bcryptjs const bcrypt = require('bcryptjs'); // Criptografar (no cadastro) const hash = await bcrypt.hash( "minhasenha", 10 ); // Comparar (no login) const match = await bcrypt.compare( "minhasenha", hash ); // match = true ou false

Modelagem

Model Usuario

code models/Usuario.js

const mongoose = require('mongoose'); const bcrypt = require('bcryptjs'); const usuarioSchema = new mongoose.Schema({ nome: { type: String, required: true }, email: { type: String, required: true, unique: true, lowercase: true }, senha: { type: String, required: true, minlength: 6 } }, { timestamps: true }); // Hook: criptografar senha antes de salvar usuarioSchema.pre('save', async function(next) { if (!this.isModified('senha')) return next(); this.senha = await bcrypt.hash(this.senha, 10); next(); }); // Método para comparar senha usuarioSchema.methods.compararSenha = function(senha) { return bcrypt.compare(senha, this.senha); }; module.exports = mongoose.model('Usuario', usuarioSchema);

Implementação

Registro e Login

code controllers/authController.js

const jwt = require('jsonwebtoken'); const Usuario = require('../models/Usuario'); // POST /auth/registrar exports.registrar = async (req, res) => { try { const usuario = await Usuario.create(req.body); const token = jwt.sign( { id: usuario._id }, process.env.JWT_SECRET, { expiresIn: '24h' } ); res.status(201).json({ token }); } catch (err) { res.status(400).json({ erro: err.message }); } }; // POST /auth/login exports.login = async (req, res) => { const { email, senha } = req.body; const usuario = await Usuario.findOne({ email }); if (!usuario || !(await usuario.compararSenha(senha))) return res.status(401).json({ erro: 'Credenciais inválidas' }); const token = jwt.sign( { id: usuario._id }, process.env.JWT_SECRET, { expiresIn: '24h' } ); res.json({ token }); };

Proteção

Middleware de autenticação

code middleware/auth.js

const jwt = require('jsonwebtoken'); module.exports = (req, res, next) => { const header = req.headers.authorization; if (!header) return res.status(401) .json({ erro: 'Token não fornecido' }); const token = header.replace( 'Bearer ', '' ); try { const decoded = jwt.verify( token, process.env.JWT_SECRET ); req.userId = decoded.id; next(); } catch { res.status(401) .json({ erro: 'Token inválido' }); } };

lock Protegendo rotas

const auth = require( '../middleware/auth' ); // Rotas públicas router.post('/registrar', ctrl.registrar); router.post('/login', ctrl.login); // Rotas protegidas router.get( '/perfil', auth, // middleware! ctrl.perfil );
lightbulb O middleware auth intercepta a requisição e verifica o token antes de chegar no controller.

Visão geral

Fluxo de autenticação

1
Registro: Usuário envia nome, email, senha → senha é criptografada com bcrypt → salva no MongoDB
2
Login: Usuário envia email + senha → bcrypt.compare valida → servidor gera JWT → retorna o token
3
Requisições protegidas: Cliente envia token no header Authorization: Bearer TOKEN
4
Middleware auth: Extrai e verifica o token → se válido, adiciona userId ao req e chama next()

Endpoints

Rotas de autenticação

route routes/authRoutes.js

const router = require('express').Router(); const ctrl = require( '../controllers/authController' ); const auth = require( '../middleware/auth' ); router.post('/registrar', ctrl.registrar); router.post('/login', ctrl.login); router.get('/perfil', auth, ctrl.perfil); module.exports = router;

api Testando com Thunder Client

POST /auth/registrar
Body: { nome, email, senha }
POST /auth/login
Body: { email, senha } → recebe token
GET /auth/perfil
Header: Authorization: Bearer TOKEN

Segurança

Boas práticas

check_circle Faça

  • Use bcrypt para hash de senhas
  • Guarde JWT_SECRET no .env
  • Defina expiração curta nos tokens (1-24h)
  • Use HTTPS em produção
  • Valide inputs do usuário

cancel NÃO faça

  • Nunca salve senhas em texto puro
  • Nunca exponha a secret key no front-end
  • Não coloque dados sensíveis no payload do JWT
  • Não confie em dados do cliente sem validar
  • Não use tokens sem expiração

Hora de praticar

Exercício prático

lock Sistema de autenticação

  1. Adicione bcrypt e jsonwebtoken ao seu projeto
  2. Crie o model Usuario com hash automático (pre save)
  3. Implemente a rota de registro (POST /auth/registrar)
  4. Implemente a rota de login (POST /auth/login)
  5. Crie o middleware de autenticação (verifica JWT)
  6. Proteja as rotas de alunos — apenas autenticados podem acessar
lightbulb Desafio extra: adicione um campo role (admin/user) e crie middleware de autorização por perfil.
Próxima aula

Aula 31

Conceitos REST, métodos HTTP e status codes.

task_alt O que aprendemos hoje

  • check_circle Autenticação vs Autorização
  • check_circle Sessão vs Token (JWT)
  • check_circle Hash de senhas com bcrypt
  • check_circle Registro, Login e geração de tokens
  • check_circle Middleware de autenticação e proteção de rotas
Próxima aula
auto_stories Referência: jwt.io
Leandro Medeiros