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

Golang Gin框架下JWT令牌在其他页面调用返回nil的问题咨询

问题解决:Gin框架中跨控制器调用c.Get("user")返回nil

核心原因

问题本质是目标路由未正确应用负责解析JWT并将user注入Context的中间件,或是中间件执行逻辑存在疏漏,导致Context中没有用户数据。

具体排查与解决步骤

1. 检查路由是否添加JWT验证中间件

Validate函数所在路由肯定配置了JWT验证中间件(该中间件会解析token、查询用户并执行c.Set("user", user)),但其他页面路由大概率遗漏了这个中间件。

  • 错误示例:
    // 仅给Validate路由加中间件
    r.GET("/validate", authMiddleware, controllers.Validate)
    // 其他路由未加中间件,导致c.Get("user")返回nil
    r.GET("/other-api", controllers.OtherHandler)
    
  • 修正方式:
    // 给需要验证用户的路由单独添加中间件
    r.GET("/other-api", authMiddleware, controllers.OtherHandler)
    // 或用路由组批量配置更高效
    authGroup := r.Group("/api")
    authGroup.Use(authMiddleware)
    {
        authGroup.GET("/validate", controllers.Validate)
        authGroup.GET("/other-api", controllers.OtherHandler)
    }
    

2. 确认中间件执行顺序与逻辑

  • 确保JWT中间件在处理函数之前执行:Gin中间件按添加顺序执行,若中间件放在处理函数之后,c.Set("user")会晚于处理函数的c.Get("user")执行,自然拿不到数据。
  • 检查中间件内是否正确设置user:确保token验证通过后,一定会执行c.Set("user", user),且没有提前return跳过该步骤。示例中间件:
    func authMiddleware(c *gin.Context) {
        // 从Header获取token
        tokenStr := c.GetHeader("Authorization")
        if tokenStr == "" {
            c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"msg": "缺少token"})
            return
        }
        // 解析token并查询用户
        claims, err := ParseToken(tokenStr)
        if err != nil {
            c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"msg": "无效token"})
            return
        }
        user, err := models.GetUserByID(claims.UserID)
        if err != nil {
            c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"msg": "用户不存在"})
            return
        }
        // 必须执行这一步,将用户注入Context
        c.Set("user", user)
        // 继续执行后续处理函数
        c.Next()
    }
    

3. 不要忽略c.Get的返回错误

你的代码中用userck, _ := c.Get("user")忽略了第二个返回值(表示key是否存在),这会掩盖问题。建议先判断存在性再做类型断言:

userck, exists := c.Get("user")
if !exists {
    c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"msg": "未授权访问"})
    return
}
user, ok := userck.(Models.User)
if !ok {
    c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"msg": "用户数据格式错误"})
    return
}
i := user.ID

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 22:33:25