Descubra neste post como proteger seus endpoints que necessitam de autenticação e controle de acesso usando o Express.js.
Por que proteger seus endpoints de API?
Os endpoints de uma API são os pontos de entrada para os dados e funcionalidades do seu sistema. Proteger esses endpoints é fundamental para evitar acessos não autorizados, roubo de dados e outras vulnerabilidades de segurança.
Vamos mostrar como implementar autenticação e controle de acesso usando middlewares e JSON Web Tokens (JWT).
Usando middleware para verificar JWT
Os middlewares processam as requisições antes que elas cheguem aos endpoints. Eles são ideais para adicionar lógicas de autenticação e autorização.
Exemplo de um endpoint simples
No exemplo abaixo, o endpoint retorna dados do dashboard. Esses dados devem ser acessíveis apenas para usuários autenticados.
app.get('/api/dashboard-data', (req, res) => {
return res.json(databoardData);
});
Implementando um middleware básico
Um middleware simples pode inspecionar os cabeçalhos da requisição:
app.use((req, res, next) => {
console.log(req.headers);
next();
});
Instalando e configurando a biblioteca JWT
A biblioteca express-jwt
facilita o processo de verificação de tokens JWT.
Instalando a Dependência
npm i express-jwt
Configurando o middleware JWT
Crie um middleware que verifique o token:
const jwt = require('express-jwt')
const checkJwt = jwt({
secret: process.env.JWT_SECRET,
algorithms: ['HS256'] // Certifique-se de usar o algoritmo correto
})
Protegendo o endpoint
Agora, aplique o middleware ao endpoint:
app.get('/api/dashboard-data', checkJwt, (req, res) => {
return res.json(databoardData);
});
Anexando o usuário à requisição
Para realizar operações que dependem do usuário autenticado, é útil anexar os dados do JWT ao objeto da requisição.
Atualizando Permissões do Usuário
No exemplo abaixo, usamos o req.user.sub
para identificar o usuário:
app.patch('/api/user-role', async (req, res) => {
try {
const { role } = req.body;
const allowedRoles = ['user', 'admin'];
if (!allowedRoles.includes(role)) {
return res.status(400).json({ message: 'Role not allowed' });
}
await User.findOneAndUpdate(
{ _id: req.user.sub },
{ role }
);
res.status(200).json({ message: 'Role updated successfully' });
} catch (error) {
res.status(500).json({ message: 'An error occurred' });
}
});
Criando um middleware para anexar o usuário
Esse middleware decodifica o token e adiciona o usuário ao objeto da requisição:
const jwtDecode = require('jwt-decode');
const attachUser = (req, res, next) => {
const token = req.headers.authorization;
if (!token) {
return res.status(401).json({ message: 'Authentication invalid' });
}
const decodedToken = jwtDecode(token.slice(7)); // Remove "Bearer "
if (!decodedToken) {
return res.status(401).json({ message: 'Invalid token' });
}
req.user = decodedToken;
next();
};
app.use(attachUser);
Limitando acesso para administradores
Algumas rotas devem ser acessíveis apenas por administradores. Vamos implementar isso de forma simples.
Middleware para verificar o papel do usuário
Este middleware impede que usuários sem permissões acessem determinados endpoints:
const requireAdmin = (req, res, next) => {
const { role } = req.user;
if (role !== 'admin') {
return res.status(403).json({ message: 'Insufficient role' });
}
next();
};
Aplicando o middleware
Proteja endpoints que contêm dados sensíveis:
app.get('/api/inventory', checkJwt, requireAdmin, (req, res) => {
return res.json(inventoryData);
});
Conclusão
A proteção de endpoints é essencial para manter a segurança da sua API e dos seus usuários. Usando middlewares, JWTs e controle de acesso baseado em papéis, você pode garantir que apenas usuários autorizados tenham acesso aos dados.