跳到主要内容
ecdsa.com
golang-jwt/jwt (Go)Go

错误信息

token has invalid claims: token is expired

也可能输出为

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

golang-jwt v4 打印的是“Token is expired”(T 大写)。v5 的其他声明错误使用同样的“token has invalid claims:”前缀。

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

含义

令牌的签名验证通过了,但 `exp` 声明的时间已经过去(即使算上你配置的容差)。golang-jwt v5 把它报告为 `ErrTokenInvalidClaims` 与 `ErrTokenExpired` 的组合;同一类错误中,`nbf` 在未来时报“token is not valid yet”,`iat` 在未来时报“token used before issued”。解析出的令牌仍会与错误一起返回,但不得信任它。

原因

修复方法

  1. 1.

    识别过期并让客户端刷新

    把 `ErrTokenExpired` 映射为带 `invalid_token` 提示的 401。客户端随后使用刷新令牌(或者重新进行身份验证)并重试。

    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.

    允许少量时钟偏差,并要求必须有 exp

    几秒的容差可以吸收机器之间的时钟漂移。`WithExpirationRequired` 堵住的是相反方向的漏洞:否则没有 `exp` 的令牌永远不会过期。

    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
    )

相关错误

浏览完整的签名错误库