Message d’erreur
token has invalid claims: token is expired
Également affiché sous la forme
- Token is expired
- token has invalid claims: token is not valid yet
- token has invalid claims: token used before issued
golang-jwt v4 affiche « Token is expired » (avec un T majuscule). Les autres erreurs de claims de la v5 utilisent le même préfixe « token has invalid claims: ».
golang-jwt/jwt (Go) — jwt.ErrTokenInvalidClaims joined with jwt.ErrTokenExpired
Ce que cela signifie
La signature du jeton a été vérifiée, mais son claim `exp` se situe dans le passé (au-delà de toute tolérance que vous avez configurée). golang-jwt v5 le signale par `ErrTokenInvalidClaims` combiné à `ErrTokenExpired` ; la même famille d’erreurs produit « token is not valid yet » pour un `nbf` situé dans le futur et « token used before issued » pour un `iat` situé dans le futur. Le jeton analysé est tout de même renvoyé avec l’erreur, mais il ne doit pas être considéré comme fiable.
Pourquoi cela se produit
Le jeton a dépassé sa durée de vie
fréquenteLes jetons d’accès vivent généralement de 5 à 60 minutes. Les clients qui mettent un jeton en cache, qui réessaient une requête bien plus tard ou qui le conservent dans une tâche de longue durée le présentent après `exp`.
L’horloge du vérificateur est en avance
fréquenteUn serveur dont l’horloge avance fait expirer chaque jeton trop tôt. Les conteneurs héritent de l’horloge de l’hôte : un seul hôte sans NTP affecte donc tous ses services.
Le client n’a aucun moyen d’actualiser le jeton
occasionnelleLes applications monopages et les CLI qui stockent un jeton d’accès mais n’utilisent jamais le jeton d’actualisation (ou ne gèrent jamais la réponse 401) échouent définitivement dès que le premier jeton expire.
exp a été écrit dans la mauvaise unité
rare`exp` est un nombre de secondes depuis l’epoch. Un émetteur qui divise deux fois les millisecondes ou qui passe par une conversion en heure locale peut émettre des jetons déjà expirés.
Comment corriger l’erreur
- 1.
Détecter l’expiration et laisser le client actualiser le jeton
Convertissez `ErrTokenExpired` en réponse 401 accompagnée de l’indication `invalid_token`. Le client utilise alors son jeton d’actualisation (ou se réauthentifie), puis réessaie.
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.
Tolérer un faible décalage d’horloge, exiger exp
Une tolérance de quelques secondes absorbe la dérive entre machines. `WithExpirationRequired` comble la faille inverse : sans cette option, les jetons dépourvus de `exp` n’expireraient jamais.
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 )