Saltar al contenido
ecdsa.com
golang-jwt/jwt (Go)Go

Mensaje de error

token has invalid claims: token is expired

También se muestra como

  • Token is expired
  • token has invalid claims: token is not valid yet
  • token has invalid claims: token used before issued

golang-jwt v4 imprime «Token is expired» (con la T mayúscula). Los demás errores de claims de la v5 usan el mismo prefijo «token has invalid claims:».

golang-jwt/jwt (Go) — jwt.ErrTokenInvalidClaims joined with jwt.ErrTokenExpired

Qué significa

La firma del token se verificó, pero su claim (declaración) `exp` está en el pasado (más allá de cualquier margen de tolerancia que hayas configurado). golang-jwt v5 lo notifica como `ErrTokenInvalidClaims` unido a `ErrTokenExpired`; la misma familia produce «token is not valid yet» para un `nbf` futuro y «token used before issued» para un `iat` futuro. El token analizado se devuelve igualmente junto con el error, pero no se debe confiar en él.

Por qué ocurre

Cómo solucionarlo

  1. 1.

    Detectar la caducidad y dejar que el cliente renueve el token

    Asigna a `ErrTokenExpired` una respuesta 401 con la indicación `invalid_token`. El cliente usa entonces su token de actualización (o vuelve a autenticarse) y reintenta.

    go
    token, err := jwt.Parse(raw, keyfunc, jwt.WithValidMethods([]string{"ES256"}))
    if errors.Is(err, jwt.ErrTokenExpired) {
    	w.Header().Set("WWW-Authenticate", `Bearer error="invalid_token", error_description="token expired"`)
    	http.Error(w, "token expired", http.StatusUnauthorized) // client refreshes and retries
    	return
    }
  2. 2.

    Tolerar un pequeño desfase de reloj y exigir exp

    Un margen de tolerancia de unos segundos absorbe la deriva entre máquinas. `WithExpirationRequired` cierra el hueco opuesto: de lo contrario, los tokens sin `exp` no caducarían nunca.

    go
    parser := jwt.NewParser(
    	jwt.WithValidMethods([]string{"ES256"}),
    	jwt.WithLeeway(30*time.Second), // absorbs clock skew for exp, nbf and iat
    	jwt.WithExpirationRequired(),   // tokens without exp are rejected too
    )

Errores relacionados

Explorar toda la base de datos de errores de firma