You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Golang JWT库验证过期Token返回Valid=true问题求助

问题原因及解决方案

核心问题

你的JWT Token使用了自定义的expiresAt字段标记过期时间,但jwt-go库默认仅验证标准JWT声明中的exp字段,不会自动处理自定义过期字段,因此即便Token实际已过期,token.Valid仍会返回true。

解决方案

有两种可行修复方式:

方案1:改用标准exp字段(推荐)

修改Token生成逻辑,将过期时间存入标准的exp字段(而非自定义的expiresAt)。这样jwt-go库会自动在jwt.Parse阶段验证过期时间,无需额外代码。

方案2:手动验证自定义expiresAt字段

若必须保留expiresAt字段,需在验证流程中手动提取并检查该字段的值:

func (m *Manager) VerifyToken(accessToken string) (int64, error) {
    fmt.Println("\nTOKEN ACCESS: ", accessToken)
    token, err := jwt.Parse(accessToken, func(token *jwt.Token) (interface{}, error) {
        return []byte(m.secretKey), nil
    })
    if err != nil {
        return -1, err
    }
    fmt.Println("TIME NOW: ", time.Now())
    fmt.Println("JWT TOKEN: ", token)
    if !token.Valid {
        return -1, errors.New("invalid token")
    }

    // 解析Token中的自定义Claims
    claims, ok := token.Claims.(jwt.MapClaims)
    if !ok {
        return -1, errors.New("failed to parse token claims")
    }

    // 提取并验证expiresAt字段
    expiresAt, ok := claims["expiresAt"].(float64)
    if !ok {
        return -1, errors.New("invalid expiresAt format")
    }
    if time.Now().Unix() > int64(expiresAt) {
        return -1, errors.New("token has expired")
    }

    // 提取用户ID并返回
    userId, ok := claims["user_id"].(float64)
    if !ok {
        return -1, errors.New("invalid user_id format")
    }
    return int64(userId), nil
}

补充说明

JWT标准定义了一组内置声明(如exp表示过期时间、nbf表示生效时间),jwt-go库会自动对这些标准声明进行合法性校验。自定义字段需要开发者手动处理验证逻辑,这就是过期Token仍能通过验证的根本原因。

内容的提问来源于stack exchange,提问作者Max

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 17:03:33