Toda autenticação bem-sucedida no DEVMOB cria uma UserSession e emite um par de tokens (accessToken + refreshToken).
A sessão é persistida server-side e consultada pelo sid do token. Esse estado permite revogar uma sessão antes da expiração do accessToken.
Estrutura dos tokens
Access Token
Token de curta duração usado no header Authorization. Ele não é persistido no banco.
| Claim | Descrição |
|---|
sub | ID do usuário (UUID) |
sid | ID da sessão (userSessionId) |
aud | Audiência da sessão: CUSTOMER, OPS, DRIVER ou BACKOFFICE |
type | access |
iat | Timestamp de emissão |
exp | Timestamp de expiração |
O access token é enviado em cada requisição via header:
Authorization: Bearer <access_token>
O access token não carrega email, dados de perfil, organizationId, membershipId, roles ou permissions. A autorização é resolvida pelo Profile e pelo domínio de Authorization.
Refresh Token
Token de longa duração usado exclusivamente para obter um novo par de tokens sem reautenticação. O cliente mantém o valor do refresh token; o DEVMOB persiste apenas seu hash em UserSession.refreshTokenHash.
| Claim | Descrição |
|---|
sub | ID do usuário (UUID) |
sid | ID da sessão (userSessionId) |
aud | Audiência da sessão |
type | refresh |
iat | Timestamp de emissão |
exp | Timestamp de expiração |
Validação por request
A sessão é rejeitada quando status = REVOKED, quando refreshExpiresAt passou ou quando inactivityExpiresAt passou. A audiência da sessão precisa bater com o aud do token.
Estratégia de refresh
A cada refresh bem-sucedido, o refresh token é rotacionado. O token anterior deixa de ser aceito porque seu hash não corresponde mais ao refreshTokenHash persistido.
Revogação
| Evento | Efeito |
|---|
| Logout | Revoga a sessão atual |
| Logout global | Revoga todas as sessões do usuário |
| Alteração de senha | Revoga sessões conforme a política de segurança do fluxo |
| Bloqueio ou remoção do usuário | Revoga todas as sessões do usuário |
| Suspeita de comprometimento | Revoga sessões selecionadas ou todas as sessões do usuário |
Revogar uma sessão atualiza status = REVOKED e preenche revokedAt. As próximas validações do sid passam a rejeitar a sessão.
Regras importantes
- O
accessToken não é armazenado no estado da sessão.
- O refresh token nunca é armazenado em texto puro nem com criptografia reversível. Apenas seu hash é persistido.
EXPIRED não é status salvo. A expiração é calculada por refreshExpiresAt, inactivityExpiresAt e exp do token.
- Mudanças em roles, memberships e permissions são refletidas pela resolução do Profile e da Authorization. A sessão não duplica esse escopo.
User.status = BLOCKED impede autenticação, refresh e uso de sessões existentes; o bloqueio deve revogar as sessões ativas do usuário.
- Nos projetos staff, a entrada continua exigindo o claim derivado da superfície correspondente (
access:ops, access:driver ou access:bko).