Autorização e Autenticação em JavaScript (Node.js)
No desenvolvimento web moderno com Node.js, a segurança dos dados do usuário e o controle de acesso são tarefas criticamente importantes. Autenticação (verificação de identidade) e autorização (verificação de permissões) são os dois pilares de qualquer sistema protegido. Neste artigo, abordaremos as principais ferramentas e bibliotecas para implementar esses mecanismos na plataforma Node.js.
Conceitos Básicos
Autenticação é o processo de verificar se o usuário é quem ele diz ser (geralmente através de login/senha, tokens ou biometria). Autorização é a determinação de quais ações e recursos estão disponíveis para um usuário autenticado (papéis, permissões de acesso).
Bibliotecas Populares para Node.js
1. Passport.js — Estratégia Universal de Autenticação
Passport.js é a biblioteca middleware mais popular para Express. Ela suporta mais de 500 estratégias: local (login/senha), OAuth2 (Google, Facebook, GitHub), JWT e muitas outras.
const passport = require('passport');const LocalStrategy = require('passport-local').Strategy;
passport.use(new LocalStrategy( function(username, password, done) { User.findOne({ username: username }, function (err, user) { if (err) { return done(err); } if (!user) { return done(null, false, { message: 'Nome de usuário inválido' }); } if (!user.validPassword(password)) { return done(null, false, { message: 'Senha inválida' }); } return done(null, user); }); }));
// Serialização e desserialização do usuáriopassport.serializeUser(function(user, done) { done(null, user.id);});
passport.deserializeUser(function(id, done) { User.findById(id, function(err, user) { done(err, user); });});2. JSON Web Tokens (JWT) — Autenticação sem Sessão
A biblioteca jsonwebtoken permite criar e verificar tokens JWT. É ideal para APIs REST e aplicações SPA.
const jwt = require('jsonwebtoken');const secretKey = process.env.JWT_SECRET;
// Criação do token no loginconst token = jwt.sign( { userId: user.id, role: user.role }, secretKey, { expiresIn: '24h' });
// Middleware para verificar o tokenfunction authMiddleware(req, res, next) { const authHeader = req.headers['authorization']; const token = authHeader && authHeader.split(' ')[1]; // Bearer TOKEN
if (!token) return res.status(401).json({ error: 'Token não fornecido' });
jwt.verify(token, secretKey, (err, decoded) => { if (err) return res.status(403).json({ error: 'Token inválido' }); req.user = decoded; next(); });}3. bcrypt — Hash Seguro de Senhas
Nunca armazene senhas em texto puro! bcrypt é o padrão ouro para hash com sal.
const bcrypt = require('bcrypt');const saltRounds = 10;
// Hash da senha no registroasync function hashPassword(plainPassword) { const salt = await bcrypt.genSalt(saltRounds); const hash = await bcrypt.hash(plainPassword, salt); return hash;}
// Verificação da senha no loginasync function checkPassword(plainPassword, hash) { return await bcrypt.compare(plainPassword, hash);}4. express-session + connect-redis — Gerenciamento de Sessões
Para aplicações web tradicionais com sessões no servidor, use express-session em conjunto com Redis para escalabilidade.
const session = require('express-session');const RedisStore = require('connect-redis')(session);
app.use(session({ store: new RedisStore({ client: redisClient }), secret: process.env.SESSION_SECRET, resave: false, saveUninitialized: false, cookie: { secure: process.env.NODE_ENV === 'production', // HTTPS httpOnly: true, maxAge: 24 * 60 * 60 * 1000 // 1 dia }}))