Pular para o conteúdo principal

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

  1. Um novo sessao_id (GUID) é gerado e salvo em superapp_usuarios.
  2. O refresh token anterior é substituído.
  3. 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çãomessage
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/refresh quando 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_id e 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.