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
相关产品推荐
相关产品推荐

