Quando vejo token expired, jwt expired ou um 401 que pode estar ligado ao tempo, o primeiro claim que normalmente verifico é exp. Não assumo que a mensagem da biblioteca explica tudo. Eu decodifico o token, converto o timestamp, comparo com o relógio do serviço que rejeitou a requisição e só então concluo se a expiração é a causa.
Para uma resposta rápida, uso o Verificador de Expiração JWT, que transforma exp, iat e nbf em horários UTC legíveis.
O que exp significa
A RFC 7519 define exp como Expiration Time. O valor é um NumericDate medido em segundos desde o Unix epoch.
Um payload pode conter:
{
"sub": "user_123",
"iat": 1789200000,
"exp": 1789203600
}
Leio iat como o horário de emissão declarado e exp como o instante a partir do qual o token não deve mais ser aceito.
A comparação conceitual é:
horário atual do verificador >= exp
Quando isso se torna verdadeiro, um verificador que aplica expiração deve rejeitar o token.
O erro mais comum: segundos versus milissegundos
JWT NumericDate usa segundos. JavaScript Date.now() usa milissegundos.
Então espero código como:
const expiresAt = payload.exp * 1000;
const expired = Date.now() >= expiresAt;
Se encontro Date.now() sendo comparado diretamente com um exp normal de 10 dígitos, as unidades estão erradas.
Esse erro também aparece quando alguém gera exp com Date.now() sem dividir por 1000, criando um timestamp absurdamente distante no futuro.
Como confirmo se o token realmente expirou
Uso esta sequência:
- Decodifico o token e confirmo que
expexiste. - Converto
exppara UTC. - Comparo com o relógio do serviço que rejeitou o token.
- Verifico
nbfeiatno mesmo contexto. - Confiro se o verificador aplica tolerância de relógio.
O passo 3 é essencial. O relógio do meu notebook não é necessariamente o relógio usado pela API, gateway ou biblioteca de autenticação.
Como penso sobre clock skew
A RFC 7519 permite uma pequena margem para diferenças de relógio entre sistemas.
Quando um token parece expirar alguns segundos antes do esperado, verifico:
- o relógio da API está sincronizado?
- o relógio do provedor de identidade está sincronizado?
- a biblioteca tem uma configuração explícita de tolerância?
Não aumento a tolerância para vários minutos apenas para fazer o erro desaparecer. Isso amplia a janela efetiva de aceitação além do valor declarado pelo emissor.
Se a diferença é de poucos segundos na fronteira, clock skew é plausível. Se o token expirou há uma hora, clock skew não é uma boa explicação.
O que faço quando exp não existe
A ausência de exp não torna todo JWT malformado automaticamente.
A especificação base define o claim, mas perfis e aplicações decidem quais claims são obrigatórios. Para um access token que deveria ser de curta duração, a ausência de exp merece investigação. Para outro tipo de JWT, a política pode ser diferente.
O Validador JWT sinaliza a ausência sem fingir que todos os perfis JWT possuem regras idênticas.
Um token não expirado ainda pode falhar
Se exp está no futuro, sigo adiante. Um JWT ativo no tempo ainda pode falhar porque:
- a assinatura não verifica;
nbfestá no futuro;issnão corresponde ao emissor confiável;audaponta para outra API;- o token veio de outro ambiente;
- o tipo de token está errado;
- scopes ou roles necessários estão ausentes.
Quando a linha do tempo parece correta, uso o Depurador JWT para comparar emissor e audiência e o Verificador de Assinatura JWT quando tenho material de chave confiável.
Por que não edito exp para renovar um token
Se um JWT assinado expirou, não altero o payload esperando que a assinatura antiga continue válida.
Trocar:
{
"exp": 1789203600
}
por um valor maior modifica os bytes assinados. Sem a credencial legítima de assinatura, o token alterado deve falhar na verificação.
A correção normal é obter um novo token pelo fluxo de refresh ou autenticação definido pelo sistema.
Como leio iat, nbf e exp juntos
Raramente olho exp isoladamente. Penso na linha do tempo:
emitido -------- janela ativa -------- expirado
iat nbf exp
Pergunto:
iatfaz sentido para o momento em que o login ocorreu?nbfestá depois do relógio atual do verificador?expvem depois deiat?- a validade declarada parece curta ou longa demais?
Uma linha do tempo estranha pode revelar erro de unidade, relógio incorreto, token de outro ambiente ou regra específica do perfil.
Meu fluxo prático para problemas de expiração
Quando suspeito de exp, sigo esta ordem:
- Abro o Verificador de Expiração JWT.
- Confirmo que
expestá em segundos, não milissegundos. - Comparo a data UTC com o relógio do serviço que rejeitou a requisição.
- Inspeciono
iatenbfem busca de contradições. - Verifico a tolerância de relógio configurada.
- Se o token realmente expirou, obtenho outro pelo fluxo legítimo.
- Se ainda está ativo, verifico assinatura, emissor e audiência.
exp é um sinal de diagnóstico muito útil, mas não é um veredito completo. Ele responde “o token está fora da janela temporal declarada?”, não “esta aplicação deve confiar e aceitar este JWT?”