As APIs REST representam o padrão fundamental para comunicação entre aplicações modernas. Node.js destaca-se como plataforma preferida para desenvolver APIs escaláveis devido à sua arquitetura orientada a eventos e performance superior. Este tutorial demonstra a criação de uma API REST completa com autenticação JWT (JSON Web Tokens).
JSON Web Tokens revolucionaram a autenticação em aplicações distribuídas. São tokens autocontidos que carregam informações do usuário codificadas e assinadas digitalmente, eliminando consultas constantes ao banco de dados e melhorando significativamente a performance das aplicações.
Configurando o Ambiente de Desenvolvimento
Inicie criando um novo projeto Node.js com as dependências necessárias:
mkdir api-jwt-tutorial && cd api-jwt-tutorial
npm init -y
npm install express jsonwebtoken bcryptjs cors helmet dotenv
npm install --save-dev nodemonAs bibliotecas incluem Express para roteamento, jsonwebtoken para manipulação de JWTs, bcryptjs para hash de senhas, cors para controle de acesso, helmet para segurança adicional e dotenv para variáveis de ambiente.
Estrutura do Servidor Base
Crie o arquivo server.js com a configuração inicial:
const express = require(\'express\');
const jwt = require(\'jsonwebtoken\');
const bcrypt = require(\'bcryptjs\');
const cors = require(\'cors\');
const helmet = require(\'helmet\');
require(\'dotenv\').config();
const app = express();
const PORT = process.env.PORT || 3000;
const JWT_SECRET = process.env.JWT_SECRET || \'sua-chave-secreta-muito-forte\';
// Middlewares de segurança
app.use(helmet());
app.use(cors());
app.use(express.json({ limit: \'10mb\' }));
app.use(express.urlencoded({ extended: true }));
// Simulação de banco de dados
let users = [];
let posts = [];
app.listen(PORT, () => {
console.log(Servidor rodando na porta ${PORT});
});Implementando Autenticação de Usuários
O sistema de autenticação requer endpoints para registro, login e validação de tokens. Implemente os controladores de usuário:
// Endpoint de registro
app.post(\'/api/register\', async (req, res) => {
try {
const { username, email, password } = req.body;
// Validações básicas
if (!username || !email || !password) {
return res.status(400).json({
error: \'Todos os campos são obrigatórios\'
});
}
if (password.length < 6) {
return res.status(400).json({
error: \'Senha deve ter pelo menos 6 caracteres\'
});
}
// Verificar se usuário já existe
const existingUser = users.find(u => u.email === email);
if (existingUser) {
return res.status(409).json({
error: \'Usuário já cadastrado\'
});
}
// Criptografar senha
const saltRounds = 12;
const hashedPassword = await bcrypt.hash(password, saltRounds);
// Salvar usuário
const newUser = {
id: users.length + 1,
username,
email,
password: hashedPassword,
createdAt: new Date().toISOString()
};
users.push(newUser);
// Remover senha da resposta
const { password: _, ...userResponse } = newUser;
res.status(201).json({
message: \'Usuário criado com sucesso\',
user: userResponse
});
} catch (error) {
res.status(500).json({ error: \'Erro interno do servidor\' });
}
});
// Endpoint de login
app.post(\'/api/login\', async (req, res) => {
try {
const { email, password } = req.body;
if (!email || !password) {
return res.status(400).json({
error: \'Email e senha são obrigatórios\'
});
}
// Buscar usuário
const user = users.find(u => u.email === email);
if (!user) {
return res.status(401).json({
error: \'Credenciais inválidas\'
});
}
// Verificar senha
const isValidPassword = await bcrypt.compare(password, user.password);
if (!isValidPassword) {
return res.status(401).json({
error: \'Credenciais inválidas\'
});
}
// Gerar JWT
const token = jwt.sign(
{
userId: user.id,
username: user.username,
email: user.email
},
JWT_SECRET,
{
expiresIn: \'24h\',
issuer: \'api-jwt-tutorial\'
}
);
res.json({
message: \'Login realizado com sucesso\',
token,
user: {
id: user.id,
username: user.username,
email: user.email
}
});
} catch (error) {
res.status(500).json({ error: \'Erro interno do servidor\' });
}
});Criando Middleware de Autenticação JWT
O middleware de autenticação intercepta requisições protegidas e valida tokens JWT:
const authenticateJWT = (req, res, next) => {
const authHeader = req.header(\'Authorization\');
if (!authHeader || !authHeader.startsWith(\'Bearer \')) {
return res.status(401).json({
error: \'Token de acesso requerido\'
});
}
const token = authHeader.substring(7); // Remove \'Bearer \'
try {
const decoded = jwt.verify(token, JWT_SECRET);
req.user = decoded;
next();
} catch (error) {
if (error.name === \'TokenExpiredError\') {
return res.status(401).json({
error: \'Token expirado\'
});
}
if (error.name === \'JsonWebTokenError\') {
return res.status(401).json({
error: \'Token inválido\'
});
}
return res.status(500).json({
error: \'Erro na validação do token\'
});
}
};Implementando Rotas Protegidas
Demonstre o uso do middleware criando endpoints para gerenciar posts:
// Listar posts (rota protegida)
app.get(\'/api/posts\', authenticateJWT, (req, res) => {
const userPosts = posts.filter(post => post.userId === req.user.userId);
res.json({
posts: userPosts,
total: userPosts.length
});
});
// Criar novo post (rota protegida)
app.post(\'/api/posts\', authenticateJWT, (req, res) => {
const { title, content } = req.body;
if (!title || !content) {
return res.status(400).json({
error: \'Título e conteúdo são obrigatórios\'
});
}
const newPost = {
id: posts.length + 1,
title,
content,
userId: req.user.userId,
author: req.user.username,
createdAt: new Date().toISOString()
};
posts.push(newPost);
res.status(201).json({
message: \'Post criado com sucesso\',
post: newPost
});
});
// Perfil do usuário (rota protegida)
app.get(\'/api/profile\', authenticateJWT, (req, res) => {
const user = users.find(u => u.id === req.user.userId);
if (!user) {
return res.status(404).json({
error: \'Usuário não encontrado\'
});
}
const { password: _, ...userProfile } = user;
res.json({
profile: userProfile,
postsCount: posts.filter(p => p.userId === user.id).length
});
});Melhorias de Segurança e Performance
Implemente recursos avançados para produção, incluindo rate limiting e refresh tokens. Para projetos que exigem alta disponibilidade, considere utilizar servidores VPS especializados que oferecem recursos dedicados para APIs Node.js.
Configure variáveis de ambiente no arquivo .env:
JWT_SECRET=sua-chave-jwt-super-secreta-de-pelo-menos-256-bits
PORT=3000
NODE_ENV=development
BCRYPT_ROUNDS=12Para aplicações em produção, integre bancos de dados como PostgreSQL ou MongoDB e implemente cache com Redis. Considere também otimizações de SEO se sua API servir conteúdo para aplicações web.
Testando a API
Teste os endpoints usando curl ou ferramentas como Postman:
Registrar usuário
curl -X POST http://localhost:3000/api/register \\
-H "Content-Type: application/json" \\
-d \'{"username":"teste","email":"teste@email.com","password":"123456"}\'
Fazer login
curl -X POST http://localhost:3000/api/login \\
-H "Content-Type: application/json" \\
-d \'{"email":"teste@email.com","password":"123456"}\'
Acessar rota protegida
curl -X GET http://localhost:3000/api/profile \\
-H "Authorization: Bearer SEU_TOKEN_JWT_AQUI"
Comentários
0Inicie sessão para deixar um comentário
Iniciar sessãoSé el primero en comentar