Sessão única SuperApp
Comportamento
O login SuperApp permite apenas uma sessão ativa por usuário. Quando o usuário faz login em outro dispositivo (ou novo login no mesmo dispositivo), a sessão anterior é encerrada imediatamente.
O que acontece no login
- Um novo
sessao_id(GUID) é gerado e salvo emsuperapp_usuarios. - O refresh token anterior é substituído.
- O JWT emitido contém a claim
sessao_id.
O que acontece no refresh
O endpoint POST /seguranca/autenticacao/token/refresh mantém o mesmo sessao_id. Apenas o refresh token e o JWT são renovados.
Validação por request
Cada request autenticada com JWT SuperApp (claim sessao_id presente) valida a sessão no banco. Se outro login tiver ocorrido, a sessão antiga deixa de ser válida.
Resposta 200 — login com sessão anterior encerrada
Quando o login SuperApp encerra uma sessão ativa, a resposta de POST /seguranca/autenticacao/token inclui a propriedade message:
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refreshToken": "abc123...",
"expiraEm": 86400,
"message": "Login realizado. A sessão em outro dispositivo foi encerrada."
}
| Situação | message |
|---|---|
| Primeiro login (sem sessão anterior) | omitida / null |
| Login em outro dispositivo | "Login realizado. A sessão em outro dispositivo foi encerrada." |
| Novo login no mesmo dispositivo | "Login realizado. A sessão anterior foi encerrada." |
O frontend pode exibir essa mensagem como aviso informativo após o login.
Resposta 401 — sessão encerrada
Quando a sessão foi invalidada (login em outro dispositivo), a API retorna:
{
"message": "Sessão encerrada. Faça login novamente."
}
Status HTTP: 401 Unauthorized
Tratamento no frontend SuperApp
async function handleApiResponse(response: Response): Promise<Response> {
if (response.status === 401) {
const data = await response.json().catch(() => ({}));
const message = data?.message ?? '';
if (message.includes('Sessão encerrada')) {
// Não tentar refresh — o refresh token também foi invalidado
clearStoredTokens();
redirectToLogin();
throw new SessionExpiredError(message);
}
}
return response;
}
function clearStoredTokens() {
localStorage.removeItem('token');
localStorage.removeItem('refreshToken');
}
Regras importantes
- Não tentar
token/refreshquando receber "Sessão encerrada" — o refresh token do dispositivo antigo já foi sobrescrito. - Redirecionar direto para a tela de login.
- Tokens SGLinear e PDVLinear não possuem claim
sessao_ide não são afetados por esta validação.
Migração de banco
Usuários com JWT antigo (sem claim sessao_id) continuam funcionando até expirar. Após novo login, passam a usar sessão única.