Skip to main content

Visão Geral da Autenticação

A API não possui rotas de login ou de refresh de token — a autenticação é feita inteiramente pelo Auth0. O backend só valida o token que o cliente já obteve do Auth0 (ou uma API Key, para integrações).

Não existe POST /auth/login nem POST /auth/refresh

O login acontece direto no Auth0 (Universal Login / SDK do frontend). Esta API nunca recebe email/senha — ela só recebe o accessToken já emitido pelo Auth0 e o valida a cada requisição.


Duas estratégias de autenticação

Toda rota (exceto as marcadas como públicas) exige um dos dois headers abaixo. A estratégia é detectada automaticamente pelo StrategyAuthGuard, nesta ordem:

OrdemHeaderEstratégiaUso típico
1x-api-keyAPI KeyIntegrações externas/servidor a servidor
2Authorization: Bearer {accessToken}JWT (Auth0)Frontend / usuários logados

Se nenhum dos dois headers estiver presente, a resposta é 401 Unauthorized com a mensagem "Credenciais não fornecidas".


JWT (Auth0)

O accessToken é um JWT RS256 assinado pelo Auth0. A validação (Auth0VerifyService) faz, nesta ordem:

  1. Decodifica o header do token para pegar o kid (key id).
  2. Busca a chave pública correspondente no JWKS do Auth0 (https://{AUTH0_DOMAIN}/.well-known/jwks.json), com cache.
  3. Verifica assinatura, audience (AUTH0_AUDIENCE) e issuer (https://{AUTH0_DOMAIN}/).
  4. Confere se o jti do token está na blacklist do Redis (auth0:blacklist:jti:{jti}) — se estiver, 401 com "Token revogado".
  5. Confere se o sub do usuário está na blacklist do Redis (auth0:blacklist:sub:{sub}) — se estiver, 401 com "Usuário desativado".
  6. Extrai accountId e userId das custom claims namespaced pelo Auth0 ({AUTH0_AUDIENCE}/accountId, {AUTH0_AUDIENCE}/userId). Sem accountId, 401 com "Token sem accountId".
Claims usadas do token

sub (ID do usuário no Auth0, ex: auth0|6a579131...), org_id (tenant/organização), permissions (array de permissões RBAC do Auth0), jti, iat, exp, aud, iss.

Erros possíveis ao validar um JWT:

SituaçãoResposta
Token sem kid no header, ou não decodificável401"Token inválido"
Assinatura, audience ou issuer inválidos, token expirado401"Credenciais inválidas"
Token sem claim jti401"Token sem jti"
jti na blacklist (logout/revogação)401"Token revogado"
sub na blacklist (usuário desativado)401"Usuário desativado"
Token sem a claim {audience}/accountId401"Token sem accountId"

Revogação de tokens

Não há um endpoint HTTP dedicado para revogar jti/sub — a blacklist é escrita diretamente no Redis por código interno (Auth0VerifyService.revokeToken / revokeUserBySub), tipicamente disparada ao desativar um usuário ou por rotinas administrativas. POST /auth/logout (veja Logout) revoga o refresh token no Auth0, não o accessToken atual — o access token continua válido até expirar ou até algo colocar seu jti/sub na blacklist.


API Key

Alternativa ao JWT para integrações. Enviada no header x-api-key. A chave é hasheada e comparada contra a tabela ApiKeys; o payload de autenticação resultante carrega accountId e o uuid da API Key (sem userId, sub ou permissions de usuário — permissões de API Key são checadas contra as permissões vinculadas à própria chave no banco).


Permissões (@CheckPermissions)

Rotas marcadas com @CheckPermissions('permissao_x', 'permissao_y') exigem que o payload autenticado tenha todas as permissões listadas:

  • JWT (Auth0): a checagem é feita contra o array permissions já embutido no token (roles/permissions configuradas no Auth0 RBAC) — não bate no banco nem no Auth0 a cada requisição.
  • API Key: a checagem consulta as permissões associadas à chave no banco local (PermissionsService.hasPermissionsApiKey).

Se faltar alguma permissão, a resposta é 403 Forbidden"Permissões insuficientes".


Rotas públicas

Rotas marcadas com @IsPublic() pulam a autenticação inteiramente (StrategyAuthGuard retorna true sem checar nenhum header). No módulo de laboratórios, por exemplo, nenhuma rota é pública; em /auth, apenas POST /auth/logout é.


Payload disponível nas rotas (@TokenPayloadParam())

Dentro de um controller, use o decorator @TokenPayloadParam() para acessar os dados extraídos do token/API Key:

async minhaRota(@TokenPayloadParam() payload: AuthPayload) {
payload.accountId; // sempre presente
payload.authType; // 'jwt' | 'api_key'
payload.userId; // só JWT
payload.sub; // só JWT
payload.orgId; // só JWT
payload.permissions; // só JWT
payload.apiKeyUuid; // só API Key
}