JSON Web Tokens, bcrypt e proteção de rotas.
Quem é você?
O que você pode fazer?
{
"alg": "HS256",
"typ": "JWT"
}
{
"userId": "123",
"email": "ana@email",
"iat": 1700000000,
"exp": 1700086400
}
Garante que o token não foi alterado. Usa a secret key do servidor para validar.
O hash é irreversível: não dá para descobrir a senha original a partir dele.
$ 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
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);
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 });
};
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' });
}
};
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
);
auth intercepta a requisição e verifica o token antes de chegar no controller.
Authorization: Bearer TOKEN
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;
.envUsuario com hash automático (pre save)role (admin/user) e crie middleware de autorização por perfil.
Conceitos REST, métodos HTTP e status codes.