Ir para o conteúdo

Solução: Erro 401 (Unauthorized) intermitente após 60 minutos

Autor: Equipe STI / Suporte Técnico
Tema da Dúvida: Autenticação WSO2 e Token JWT
Data da Solução: 10/10/2025


❓ Detalhamento da Dúvida / Problema

Contexto:
Diversas certificadoras relataram que o sistema de integração deles para de funcionar subitamente após cerca de uma hora de operação contínua, mesmo que a primeira requisição de login tenha sido feita corretamente com a Access Key e Secret Key.

Erro ou Comportamento Inesperado:
As chamadas de API (ex: GET /animal/list) passam a retornar HTTP 401 Unauthorized de forma constante, bloqueando a sincronização. Apenas reiniciando a aplicação da certificadora o fluxo volta ao normal.


💡 Descrição da Solução

O problema ocorre porque os Tokens JWT emitidos pela API do SISBOV têm uma validade (TTL - Time to Live) estrita de 60 minutos por questões de segurança. O token não é vitalício.

Muitos sistemas integradores fazem a chamada POST /integracao/auth/system durante a inicialização da aplicação e tentam reutilizar o mesmo "Bearer Token" indefinidamente num cache estático.

Correção / Passos para Resolver

  1. A certificadora deve monitorar o tempo de vida do token (ou capturar proativamente o código HTTP 401).
  2. Ao receber um 401 (ou pouco antes de o token expirar, inspecionando o "claim" exp do JWT), a aplicação deve obrigatoriamente realizar uma nova chamada de autenticação com suas chaves de acesso.
  3. O novo token gerado deve substituir o antigo no cache/header das próximas chamadas.

💻 Solução Programática (Se aplicável)

O comportamento ideal é implementar um Interceptor ou fluxo de Retry na comunicação HTTP do sistema cliente.

def fazer_requisicao_api(endpoint, payload):
    token = obter_token_em_cache()

    # Faz a chamada com o token atual
    resposta = http_client.post(endpoint, json=payload, headers={"Authorization": f"Bearer {token}"})

    # Se expirar, renova e tenta de novo
    if resposta.status_code == 401:
        novo_token = realizar_login_apiSISBOV(access_key, secret_key)
        salvar_token_em_cache(novo_token)

        # Repete a requisição com sucesso
        resposta = http_client.post(endpoint, json=payload, headers={"Authorization": f"Bearer {novo_token}"})

    return resposta

Embora o retry no 401 seja eficaz, a melhor prática é decodificar o token localmente e renová-lo antes do vencimento:

// Exemplo em Node.js
const jwtContent = parseJwt(token);
const tempoRestanteSegundos = jwtContent.exp - (Date.now() / 1000);

// Se faltarem menos de 2 minutos, já atualiza proativamente
if (tempoRestanteSegundos < 120) {
    renovarTokenBaseSISBOV();
}