Se você ainda está validando JWT dentro de cada serviço manualmente…
você está fazendo errado.
Microserviço sério precisa de:
separação de responsabilidade
segurança centralizada
validação padronizada
Vamos montar isso do jeito certo.
1. Arquitetura correta (produção)
Estrutura base:
[ Client ]
↓
[ API Gateway ]
↓
[ Auth Service ] → gera JWT
↓
[ Microservices (Resource Servers) ]👉 Regra de ouro:
Auth Service = gera token
Gateway = valida entrada
Microservices = confiam no token
2. Estrutura do JWT
Exemplo de payload:
{
"sub": "user@email.com",
"userId": 1,
"roles": ["ROLE_USER"],
"tenantId": "church_001",
"iat": 1710000000,
"exp": 1710003600
}👉 Nunca coloque:
senha
dados sensíveis
3. Gerando chave segura (ESSENCIAL)
Erro clássico:
👉 chave fraca → vulnerável
Use no mínimo 256 bits:
Key key = Keys.secretKeyFor(SignatureAlgorithm.HS256);Ou via Base64:
SecretKey key = Keys.hmacShaKeyFor(Base64.getDecoder().decode(secret));4. Auth Service (Spring Boot 3.4+)
Dependências:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
</dependency>JwtService
@Service
public class JwtService {
private final SecretKey key = Keys.secretKeyFor(SignatureAlgorithm.HS256);
public String generateToken(User user) {
return Jwts.builder()
.subject(user.getEmail())
.claim("userId", user.getId())
.claim("roles", user.getRoles())
.claim("tenantId", user.getTenantId())
.issuedAt(new Date())
.expiration(new Date(System.currentTimeMillis() + 3600000))
.signWith(key)
.compact();
}
public Claims extractClaims(String token) {
return Jwts.parser()
.verifyWith(key)
.build()
.parseSignedClaims(token)
.getPayload();
}
}5. Endpoint de login
@RestController
@RequestMapping("/auth")
@RequiredArgsConstructor
public class AuthController {
private final JwtService jwtService;
@PostMapping("/login")
public ResponseEntity<?> login(@RequestBody LoginRequest request) {
// validar usuário (DB)
User user = authenticate(request);
String token = jwtService.generateToken(user);
return ResponseEntity.ok(Map.of(
"token", token
));
}
}6. Refresh Token (produção)
👉 Token curto + refresh longo
Tabela:
CREATE TABLE refresh_token (
id BIGINT PRIMARY KEY,
token VARCHAR(255),
user_id BIGINT,
expiry_date TIMESTAMP,
revoked BOOLEAN
);Serviço:
public String refreshToken(String oldToken) {
RefreshToken token = findValidToken(oldToken);
return jwtService.generateToken(token.getUser());
}7. API Gateway (Spring Cloud Gateway)
Dependência:
<artifactId>spring-cloud-starter-gateway</artifactId>Filtro JWT
@Component
public class JwtAuthenticationFilter implements GlobalFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
String auth = exchange.getRequest()
.getHeaders()
.getFirst(HttpHeaders.AUTHORIZATION);
if (auth == null || !auth.startsWith("Bearer ")) {
return chain.filter(exchange);
}
String token = auth.substring(7);
// validar token aqui (ou via lib)
return chain.filter(exchange);
}
}8. Microserviços como Resource Server
👉 Aqui é onde fica profissional
Dependência:
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>Configuração
spring:
security:
oauth2:
resourceserver:
jwt:
secret-key: SUA_CHAVE_BASE64SecurityConfig
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
return http
.csrf(csrf -> csrf.disable())
.authorizeHttpRequests(auth -> auth
.requestMatchers("/public/**").permitAll()
.anyRequest().authenticated()
)
.oauth2ResourceServer(oauth2 -> oauth2.jwt())
.build();
}9. Acessando dados do usuário
@GetMapping("/me")
public String me(@AuthenticationPrincipal Jwt jwt) {
return jwt.getClaim("userId").toString();
}10. Boas práticas de produção
Use HTTPS sempre
Use expiração curta (15min)
Use refresh token
Nunca confie no frontend
Use roles no token
Use multi-tenant (tenantId)
Erros que você NÃO pode cometer
Validar token manual em cada service
Usar chave fraca
Não ter refresh token
Token sem expiração
Misturar autenticação com regra de negócio
Conclusão
JWT em microserviço não é só gerar token.
É arquitetura.
Se fizer certo:
escalável
seguro
limpo
Se fizer errado: 👉 vira dor de cabeça em produção.
