b. JWT
O primeiro passo para construir a camada de segurança é entender os JSON Web Tokens (JWT) e criar o módulo de interface auth, que define o contrato da API de autenticação.
1. JSON Web Token
O JWT é uma forma compacta e segura para URLs de representar claims (afirmações) entre duas partes. É o padrão usado pela plataforma para transportar a identidade do usuário autenticado entre os serviços sem armazenar estado de sessão no servidor — o que o torna naturalmente compatível com a escalabilidade horizontal.
Um JWT é composto de três partes codificadas em Base64Url, separadas por pontos.
Exemplo de JWT
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJpc3MiOiJJbnNwZXIiLCJpYXQiOjE3MDMwMDgzMzgsImV4cCI6MjAxODU0MTEz
OCwiYXVkIjoid3d3Lmluc3Blci5lZHUuYnIiLCJzdWIiOiJodW1iZXJ0b3JzQGluc3Blci5lZHUuYnIiLCJHaXZlbk5hbWUiOiJId
W1iZXJ0byIsIlN1cm5hbWUiOiJTYW5kbWFubiIsIkVtYWlsIjoiaHVtYmVydG9yc0BpbnNwZXIuZWR1LmJyIiwiUm9sZSI6IlByb2
Zlc3NvciJ9.SsGdvR5GbYWTRbxY7IGxHt1vSxhkpRueBJWsi0lrPhJVCICp119QjU8F3QvHW0yF5tw-HhQ9RVh0l89t4M0LNw
O header normalmente tem duas partes: o tipo do token (JWT) e o algoritmo de assinatura usado, como HMAC SHA256 ou RSA.
{
"iss": "Insper",
"iat": 1703008338,
"exp": 2018541138,
"aud": "www.insper.edu.br",
"sub": "humbertors@insper.edu.br",
"GivenName": "Humberto",
"Surname": "Sandmann",
"Email": "humbertors@insper.edu.br",
"Role": "Professor"
}
O payload contém as claims. Claims são afirmações sobre uma entidade (normalmente, o usuário) e dados adicionais. Há três tipos de claims: registradas, públicas e privadas. As claims registradas são um conjunto de claims predefinidas, não obrigatórias, mas recomendadas, que oferecem um conjunto de claims úteis e interoperáveis. Alguns exemplos são iss (emissor), exp (instante de expiração), sub (assunto) e aud (público-alvo). As claims públicas podem ser definidas livremente por quem usa JWTs; para evitar colisões, elas devem ser registradas no IANA JSON Web Token Registry ou definidas como uma URI que contenha um namespace resistente a colisões. As claims privadas são claims personalizadas, criadas para compartilhar informações entre partes que concordam em usá-las, e não são nem registradas nem públicas.
Chave secreta
A chave secreta usada para assinar o JWT deve ser mantida em sigilo. Qualquer pessoa com acesso a ela pode forjar tokens. Armazene-a como variável de ambiente — nunca a escreva diretamente no código-fonte.
As principais claims usadas nesta plataforma são:
| Claim | Campo | Descrição |
|---|---|---|
jti | id | O identificador único da conta |
sub | subject | O nome da conta |
iss | issuer | A plataforma emissora |
nbf | notBefore | O token passa a ser válido neste instante |
exp | expiration | O token expira neste instante |
Depois de um login bem-sucedido, o servidor gera um JWT, coloca-o em um cookie HttpOnly e o devolve ao navegador. Em cada requisição seguinte, o navegador envia o cookie automaticamente — o Gateway o lê e resolve a identidade sem pedir que o usuário faça login de novo.
sequenceDiagram
autonumber
actor User
User->>+Auth Service: login (email + senha)
Auth Service->>Auth Service: valida as credenciais e gera o JWT
Auth Service->>-User: Set-Cookie: __store_jwt_token=<jwt>
User->>User: o navegador armazena o cookie
User->>Gateway: as requisições seguintes levam o cookie automaticamente 2. O módulo de interface auth
O módulo auth segue o mesmo padrão do módulo account: é uma biblioteca (e não uma aplicação executável) que define o contrato da API e os DTOs compartilhados entre o auth-service e qualquer outro microsserviço que precise chamar os endpoints de autenticação via Feign.
2.1 Repositório
Crie um novo repositório git para a interface auth e adicione-o como submódulo:
2.2 Código
Use o Spring Initializr para gerar um projeto Maven com as seguintes configurações:
- Group:
store - Artifact:
auth - Package name:
store.auth - Packaging: Jar
- Java: 25
Dependências a adicionar:
- Lombok — reduz o código repetitivo (boilerplate) com processamento de anotações em tempo de compilação
- OpenFeign — cliente HTTP declarativo para chamadas entre serviços
Apague o AuthApplication.java, o src/test/ e o src/main/resources/ — este módulo é uma biblioteca, não um serviço executável.
A estrutura resultante é:
📁 api/
└── 📁 auth/
├── 📁 src/
│ └── 📁 main/
│ └── 📁 java/
│ └── 📁 store/
│ └── 📁 auth/
│ ├── AuthController.java
│ ├── LoginIn.java
│ ├── RegisterIn.java
│ └── TokenOut.java
└── pom.xml
Código-fonte
O endpoint /auth/solve
O solveToken é um endpoint interno, chamado apenas pelo Gateway. Ele recebe a string bruta do JWT e retorna o idAccount correspondente. Ele nunca é exposto diretamente ao navegador.
2.3 Instalação
Instale a interface no repositório Maven local para que o auth-service possa depender dela:
Pronto! A interface auth está pronta. Na próxima seção, vamos implementar o auth-service, incluindo o JwtService, que assina e valida os tokens, e o AuthService, que orquestra o login e o cadastro.