Pular para o conteúdo principal

Fluxo de Autenticação

Diagrama

sequenceDiagram
participant S as Fornecedor
participant A as API Hub
participant DB as PostgreSQL

Note over S,A: 1. Emissão (uma vez, ou após expiração do refresh)
S->>A: POST /api/external-auth/token<br/>x-api-key: <chave-fixa>
A->>DB: Carrega suppliers ativos
A->>A: Verifica hash PBKDF2 (tempo constante)
A->>DB: Persiste refresh token (hashed)
A-->>S: { access_token, refresh_token }

Note over S,A: 2. Chamadas de negócio (~15 min)
S->>A: GET /api/external/ping<br/>Authorization: Bearer <access_token>
A->>A: Valida JWT (issuer, audience, exp, assinatura)
A-->>S: 200 OK

Note over S,A: 3. Renovação (quando access_token expira)
S->>A: POST /api/external-auth/refresh<br/>{ "refreshToken": "..." }
A->>DB: Busca por hash do refresh token
A->>A: Verifica: não revogado, não expirado
A->>DB: Revoga token antigo (rotation)
A->>DB: Persiste novo refresh token (hashed)
A-->>S: { access_token, refresh_token } (novos)

Note over S,A: 4. Encerramento de sessão
S->>A: POST /api/external-auth/revoke<br/>{ "refreshToken": "..." }
A->>DB: Marca como revogado
A-->>S: 204 No Content

Estados do refresh token

ATIVO

├── /refresh ──► REVOGADO (reason: "rotation")
│ + novo token ATIVO criado

├── /revoke ──► REVOGADO (reason: "manual-revoke")

└── expirou ──► EXPIRADO (passivo)

REVOGADO apresentado em /refresh:
└── REUSE DETECTED ──► todos os tokens ATIVOS do supplier são REVOGADOS
(reason: "reuse-detected")
Supplier precisa se re-autenticar com a API key

Reuse detection

Se um refresh token já revogado for apresentado novamente, o sistema assume que houve roubo de token e encerra toda a sessão do fornecedor:

  1. Loga warning com supplierId + IP (nunca o token em si).
  2. Carrega todos os tokens ativos do fornecedor.
  3. Revoga todos com RevocationReason = "reuse-detected".
  4. Retorna 401 invalid_grant.

O fornecedor precisa usar a API key novamente para iniciar uma nova sessão.