Quando uma API informa que o JWT expirou, primeiro confirmo o exp em vez de aceitar a mensagem como diagnóstico completo. Comparo o timestamp com o relógio do verificador e só depois decido se preciso obter outro token ou se o 401 esconde outro problema.
Meu ponto de partida é o Verificador de Expiração JWT, porque ele mostra exp, iat, nbf, o horário UTC e o tempo restante.
1. Confirmo se exp realmente ficou no passado
A RFC 7519 define exp como o instante depois do qual o token não deve mais ser aceito.
Com:
{
"iat": 1789200000,
"exp": 1789203600
}
lembro que os valores são segundos NumericDate.
Em JavaScript:
const expired = Date.now() >= payload.exp * 1000;
Prefiro converter para UTC, especialmente quando comparo logs de vários serviços.
2. Comparo com o relógio da API
Quem rejeita o token usa o próprio relógio. Por isso comparo:
expdecodificado;- horário da API;
- horário do provedor de identidade;
- tolerância de relógio configurada.
Alguns segundos de diferença na fronteira podem ser clock skew. Um token expirado há dezenas de minutos não é um bom candidato para essa explicação.
Também não amplio a tolerância excessivamente para “resolver” o erro. Isso aumenta a janela efetiva de validade além da intenção do emissor.
3. Verifico se o 401 realmente significa expiração
Em OAuth bearer tokens, a RFC 6750 usa invalid_token para situações que podem incluir token expirado, revogado, malformado ou inválido por outra razão.
Posso encontrar:
401 Unauthorized
invalid_token
token expired
jwt expired
signature has expired
Se o servidor aponta explicitamente expiração e exp confirma, o diagnóstico é forte. Se a resposta é apenas 401, continuo investigando.
4. Escolho o fluxo legítimo de renovação
Se o token realmente expirou, não edito o payload.
Mudar:
{"exp": 1789203600}
para uma data posterior altera os bytes assinados. A assinatura original deve deixar de verificar.
A recuperação correta normalmente é uma destas:
- obter novo access token pelo refresh flow;
- autenticar novamente se refresh não estiver disponível;
- corrigir o cliente se ele está guardando e reutilizando access tokens antigos.
O decoder serve para inspeção, não para “renovar” credenciais.
Access token e refresh token não são intercambiáveis
Em OAuth, o access token é normalmente enviado à API. O refresh token, quando existe, é enviado ao authorization server para solicitar outro access token.
Não colo refresh tokens reais em ferramentas de depuração. Eles podem ser credenciais de vida mais longa e maior valor do que o access token expirado que estou tentando analisar.
Se exp ainda está no futuro
Nesse ponto, deixo de tratar o caso como “JWT expirado”. Verifico:
nbfestá no futuro?- a assinatura verifica com uma chave confiável?
isscorresponde ao issuer esperado?audcorresponde à API atual?- o cliente enviou access token, ID token ou outro token?
- existe política de revogação ou idade máxima independente de
exp?
O Validador JWT ajuda nas checagens comuns; o Depurador JWT é melhor quando conheço issuer e audience esperados.
E se exp não existir?
Não trato ausência de exp como erro sintático universal. Perfis específicos definem quais claims são obrigatórios.
Para um bearer access token de curta duração, eu investigaria a ausência de exp com atenção. Para outro perfil JWT, a regra pode ser diferente.
Um token expirado ainda pode ter assinatura válida
Esses resultados não se contradizem.
Um JWT pode ser:
- Base64URL correto;
- JSON válido;
- assinatura criptograficamente válida;
- issuer correto;
- audience correta;
- e ainda estar expirado.
A assinatura prova integridade em relação à chave confiável. A expiração é uma regra separada de aceitação.
Então, se o Verificador de Assinatura JWT diz “assinatura verificada” mas exp está no passado, aceito ambas as conclusões: o token é autêntntico em relação à chave, porém sua janela temporal terminou.
Meu checklist de JWT expirado
- Abro o Verificador de Expiração JWT.
- Confirmo
expem segundos desde o epoch. - Comparo com o relógio do verificador.
- Inspeciono
iatenbf. - Confiro se a mensagem do servidor realmente identifica expiração.
- Se expirou, obtenho outro token por refresh ou autenticação.
- Nunca edito
expe reutilizo a assinatura antiga. - Se
expainda está no futuro, avanço para assinatura, issuer e audience.
Para detalhes do timestamp, consulto o guia de claim exp do JWT. Se o tempo parece correto mas o erro continua, sigo o fluxo de JWT 401 Unauthorized.
A distinção prática é: um JWT expirado pode estar perfeitamente bem formado e corretamente assinado; ele é rejeitado porque sua janela de aceitação acabou.