Esta é uma API de autenticação de usuários desenvolvida em Java com Spring Boot 3.3.1, que utiliza tokens JWT para segurança. A API permite a criação de contas e login, além de realizar a verificação de e-mail por meio da geração de tokens aleatórios usando UUID. Para o envio de e-mails, a aplicação integra o serviço do Gmail utilizando o spring-boot-starter-mail.
Além disso, os tokens de verificação são armazenados no Redis junto com o e-mail do usuário para garantir validade e facilitar a validação durante o processo de confirmação.
- Tecnologias
- Dependências
- Requisitos
- Estrutura de Pastas
- CORS
- JWT e Segurança
- Endpoints
- Fluxo de Autenticação
- Como instalar o projeto
- Como usar a API
- Erros Comuns
- Features
- Configurações Importantes
- Testes
- Links
- Versioning
- Authors
| Dependência | Versão | Descrição | Escopo |
|---|---|---|---|
| Spring Boot Starter Data JPA | 3.3.1 | Persistência de dados com JPA/Hibernate | (padrão) |
| Spring Boot Starter Web | 3.3.1 | Framework web para APIs RESTful | (padrão) |
| Spring Boot Starter Mail | 3.3.1 | Suporte a envio de e-mails | (padrão) |
| Spring Boot Starter Thymeleaf | 3.3.1 | Template engine para views HTML | (padrão) |
| Java JWT (Auth0) 4.4.0 | 4.4.0 | Geração e validação de JSON Web Tokens | (padrão) |
| Spring Boot Starter Security | 3.3.1 | Segurança autenticação e autorização | (padrão) |
| Spring Boot Starter Data Redis | 3.3.1 | Integração com Redis para cache/mensagens | (padrão) |
| MySQL Connector/J | - | Driver JDBC para MySQL | runtime |
| H2 Database | - | Banco em memória para testes | test |
| embedded-redis 0.7.3 | 0.7.3 | Redis embarcado para testes | test |
| Spring Boot Starter Test | 3.3.1 | Framework de teste do Spring Boot | test |
| Spring Security Test | 3.3.1 | Testes de segurança | test |
Requisitos:
- Java 21
- Maven 3.6+
- MySQL 8.0+
- Redis 6.0+
.github/
├── workflows/
│ └── java-ci.yml # Workflow para build e test da aplicação
│
docker/
├── docker-compose.yaml # MySQL e Redis para desenvolvimento
├── Dockerfile # Imagem da aplicação (JAR)
│
src/
├── main/
│ ├── java/
│ │ └── dev/felipemlozx/api_auth/
│ │ ├── controller/ # Endpoints da API (REST Controllers)
│ │ ├── core/ # Classes para transição de dados entre módulos
│ │ ├── dto/ # Objetos de transferência de dados (Request/Response)
│ │ ├── entity/ # Entidades JPA (Mapeadas para o banco de dados)
│ │ ├── repository/ # Interfaces de acesso ao banco (JPA)
│ │ ├── infra/ # Configuração de infraestrutura
│ │ └── config/ # Configuração de dependências gerais ou de dependências externas (Redis, CORS)
│ │ └── security/ # Configuração de segurança da aplicação (filtro de request, jwt, etc)
│ │ ├── services/ # Regras de negócio e lógica da aplicação
│ │ └── utils/ # Classes utilitárias
│ └── resources/
│ └── application.yaml # Configurações (Porta, banco, JWT, etc)
│ └── templates/ # Templates para o envio de email
└── test/
└── java/ ... # Testes unitários e de integração (H2 + Redis embarcado)
- Origem permitida:
http://localhost:4200 - Métodos:
GET, POST, PUT, DELETE, OPTIONS - Credenciais:
false
Caso precise liberar outras origens, ajuste em WebConfig (dev.felipemlozx.api_auth.infra.config.WebConfig).
- Context path:
/api/v1 - Endpoints públicos:
POST /auth/login,POST /auth/register,GET /auth/verify-email/**,GET /auth/refresh,POST /auth/resend-verification-email/** - Endpoints protegidos: demais rotas exigem
Authorization: Bearer <accessToken> - Claims do Access Token:
id,name,email,roles - Expiração: Access Token (1h), Refresh Token (7 dias)
A chave secreta do JWT é lida da propriedade api.secret.key (pode ser definida via variável de ambiente, ver seção de variáveis).
| Método | Rota | Descrição | Autenticação |
|---|---|---|---|
| POST | /api/v1/auth/register |
Cadastra um novo usuário | ❌ |
| POST | /api/v1/auth/login |
Autentica usuário e retorna JWT | ❌ |
| GET | /api/v1/auth/verify-email/{token} |
Verifica o e-mail do usuário com o token | ❌ |
| GET | /api/v1/auth/refresh |
Renova o access token usando refresh token | ❌ |
| POST | /api/v1/auth/resend-verification-email/ |
Reenvia e-mail de verificação (configurado mas não implementado) | ❌ |
| GET | /api/v1/club/secret |
Rota protegida só para usuários logados e com e-mail verificado | ✅ |
-
Cadastro:
/api/v1/auth/registercria o usuário e envia e-mail de verificação. -
Verificar e-mail:
/api/v1/auth/verify-email/{token}verifica o e-mail com otokenenviado para o e-mail cadastrado. -
Login:
/api/v1/auth/loginretorna Access + Refresh Tokens. -
Renovação de Token:
/api/v1/auth/refreshpermite renovar o access token usando o refresh token (headerX-Refresh-Token). -
Acesso protegido: Endpoints protegidos exigem Access Token no header
Authorization: Bearer <token>.
Esta seção te guiará passo a passo para configurar e executar a API de autenticação em sua máquina local.
Antes de começar, certifique-se de ter instalado:
- Java 21 - Download oficial
- Maven 3.6+ - Download oficial
- MySQL 8.0+ - Download oficial
- Redis 6.0+ - Download oficial
- Git - Download oficial
Caso prefira, use Docker para executar MySQL e Redis. Veja abaixo.
- Inicie o servidor MySQL em sua máquina
- Crie um novo banco de dados:
CREATE DATABASE testeDb;
- Crie um usuário (opcional, mas recomendado):
CREATE USER 'dev'@'localhost' IDENTIFIED BY 'teste123'; GRANT ALL PRIVILEGES ON testeDb.* TO 'dev'@'localhost'; FLUSH PRIVILEGES;
- Verifique se as configurações no arquivo
application.yamlestão corretas:spring: datasource: url: jdbc:mysql://localhost:3306/testeDb username: dev password: teste123
- Inicie o servidor Redis em sua máquina:
redis-server
- Verifique se está rodando na porta padrão 6379:
redis-cli ping # Deve retornar: PONG - Ou ajuste a configuração no
application.yamlse necessário:spring: data: redis: host: localhost port: 6379
Para enviar e-mails de verificação, você precisa configurar o Gmail:
- Ative a verificação em duas etapas na sua conta Google
- Gere uma senha de app:
- Acesse Conta Google
- Segurança → Verificação em duas etapas → Senhas de app
- Gere uma senha para "Email"
- Configure a variável de ambiente:
export EMAIL_PASSWORD="sua_senha_de_app_aqui"
- Ou adicione no arquivo
application.yaml(não recomendado para produção):spring: mail: username: seu_email@gmail.com password: ${EMAIL_PASSWORD}
Se preferir usar Docker para MySQL e Redis:
# MySQL
docker run --name mysql-auth -e MYSQL_ROOT_PASSWORD=root -e MYSQL_DATABASE=testeDb -e MYSQL_USER=dev -e MYSQL_PASSWORD=teste123 -p 3306:3306 -d mysql:8.0
# Redis
docker run --name redis-auth -p 6379:6379 -d redis:6.2-alpineObservação: A propriedade
api.secret.keypode ser definida via variável de ambienteAPI_SECRET_KEY(Spring faz o binding automaticamente).
-
Clone o repositório:
git clone https://github.com/felipemelozx/api-auth.git cd api-auth -
Compile o projeto:
mvn clean install
-
Execute a aplicação:
mvn spring-boot:run
-
Acesse a aplicação em
http://localhost:8080/api/v1
| Problema | Solução |
|---|---|
Connection refused no MySQL |
Verifique se o MySQL está rodando na porta 3306 |
Connection refused no Redis |
Verifique se o Redis está rodando na porta 6379 |
Email authentication failed |
Verifique a senha de app do Gmail |
Port 8080 already in use |
Mude a porta no application.yaml ou pare outros serviços |
Agora que você tem a aplicação rodando, vamos aprender como usar cada endpoint e testar a funcionalidade.
| Endpoint | Método | Descrição | Autenticação |
|---|---|---|---|
/api/v1/auth/register |
POST | Cadastra um novo usuário | ❌ Público |
/api/v1/auth/login |
POST | Autentica usuário e retorna JWT | ❌ Público |
/api/v1/auth/verify-email/{token} |
GET | Verifica e-mail com token | ❌ Público |
/api/v1/auth/refresh |
GET | Renova access token (header X-Refresh-Token) |
❌ Público |
/api/v1/auth/resend-verification-email/{email} |
POST | Reenvia e-mail de verificação | ❌ Público |
/api/v1/club/secret |
GET | Rota protegida com frases motivacionais | ✅ JWT obrigatório |
- Registre um usuário → Receba confirmação de criação
- Verifique seu e-mail → Clique no link enviado ou use o token
- Faça login → Receba access e refresh tokens
- Acesse rota protegida → Use o access token no header Authorization
- Teste renovação → Use o refresh token quando necessário
POST /api/v1/auth/register
Content-Type: application/json
{
"username": "UserNameTest",
"email": "Test@email.com",
"password": "Strong#123"
}Resposta de sucesso:
HTTP/1.1 201 Created
Content-Type: application/json
{
"success": true,
"message": "User created. Verify your email.",
"data": null
}Resposta com erros de validação:
HTTP/1.1 400 Bad Request
Content-Type: application/json
{
"success": false,
"message": "Validation errors",
"data": [
"Username must be at least 3 characters long",
"Email must be valid",
"Password must contain at least 8 characters, one uppercase, one lowercase, one number and one special character"
]
}POST /api/v1/auth/login
Content-Type: application/json
{
"username": "UserNameTest",
"password": "Strong#123"
}Resposta de sucesso:
HTTP/1.1 200 OK
Content-Type: application/json
{
"success": true,
"message": "Success",
"data": {
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
}Resposta com erro - Email não verificado:
HTTP/1.1 403 Forbidden
Content-Type: application/json
{
"success": false,
"message": "Email not verified",
"data": null
}Resposta com erro - Credenciais inválidas:
HTTP/1.1 403 Forbidden
Content-Type: application/json
{
"success": false,
"message": "User or password is incorrect",
"data": null
}GET /api/v1/auth/verify-email/{token}Resposta de sucesso:
HTTP/1.1 200 OK
Content-Type: application/json
{
"success": true,
"message": "Email verified",
"data": null
}Resposta com erro - Token inválido/expirado:
HTTP/1.1 400 Bad Request
Content-Type: application/json
{
"success": false,
"message": "Invalid or expired token",
"data": null
}GET /api/v1/auth/refresh
X-Refresh-Token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...Resposta de sucesso:
HTTP/1.1 200 OK
Content-Type: application/json
{
"success": true,
"message": "Success",
"data": {
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
}POST /api/v1/auth/resend-verification-email/{email}- Sucesso:
204 No Content - Possíveis erros:
400(email não encontrado, tempo de verificação expirado, já verificado),500(falha no envio de e-mail)
GET /api/v1/club/secret
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...Resposta de sucesso:
HTTP/1.1 200 OK
Content-Type: application/json
{
"success": true,
"message": "Success",
"data": "UserNameTest are authorization user@email.com Cada desafio é uma oportunidade de crescimento."
}| Código | Mensagem | Causa |
|---|---|---|
| 400 | Validation errors |
Dados de entrada inválidos |
| 400 | Invalid or expired token |
Token de verificação inválido/expirado |
| 401 | REFRESH_TOKEN_INVALID |
Refresh Token inválido ou revogado |
| 403 | Email not verified |
E-mail não foi verificado |
| 403 | User or password is incorrect |
Credenciais inválidas |
| 403 | User not register |
Usuário não encontrado |
| 409 | User already exists |
Email já cadastrado |
As principais funcionalidades da aplicação são:
- ✅ Registro e autenticação de usuários
- ✅ Autenticação baseada em JWT com access e refresh tokens
- ✅ Sistema de verificação de e-mail
- ✅ Armazenamento de tokens no Redis
- ✅ Renovação automática de tokens
- ✅ Rota protegida com frases motivacionais
- ✅ Validação de dados de entrada
- ✅ Criptografia de senhas com BCrypt
- ✅ Configuração de segurança com Spring Security
- ✅ Suporte a cache com Redis
- ✅ Envio de e-mails com templates HTML
# Senha do Gmail (obrigatória)
export EMAIL_PASSWORD="sua_senha_de_app_aqui"
# URL base para o link de verificação, (Url do front-end onde vai ter a request para o back-end)
export API_URL="http://localhost:4200/verify-email/"
# Chave secreta do JWT (obrigatória em ambientes não locais)
export API_SECRET_KEY="minha_chave_segura"Dica: O Spring Boot faz binding automático de variáveis de ambiente.
API_SECRET_KEYsubstituiapi.secret.keydoapplication.yamlse definida.
- MySQL: Porta 3306, banco
testeDb - Redis: Porta 6379, cache com TTL de 5 minutos (config Geral) e 15 minutos via
RedisCacheManager - JPA: DDL auto-update habilitado
- Execute:
mvn test - Banco de testes: H2 em memória
- Redis de testes: Redis embarcado (
embedded-redis 0.7.3)
- Repository: https://github.com/felipemelozx/api-auth
0.0.1-SNAPSHOT
Please follow GitHub and join us! Thanks for visiting and happy coding!