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

Gorilla Websocket结合Cookie-JWT认证失败问题求助

问题:Gorilla Websocket结合JWT Cookie认证异常

我尝试使用Gorilla Websocket实现图表功能,采用Cookie携带JWT令牌的认证中间件。所有HTTP接口均可正常工作,但WebSocket接口出现异常:WebSocket连接中Cookie为空,且Context内无法获取到jwt值。若移除连接升级器,Cookie和Context可正常传递,但升级为WebSocket协议后便会失败。其他接口均正常工作,关闭中间件后WebSocket也可正常运行。补充JWT验证、生成函数及登录接口代码后,最终发现问题出在Postman的请求Cookie设置错误。

相关代码

路由配置

func (r *router) routes(engine *gin.Engine) {
    engine.Use(r.handler.VerifyUser())

    engine.POST("/signup", r.handler.CreateUser)
    engine.POST("/signin", r.handler.LoginUser)
    engine.GET("/welcome", r.handler.Welcome)
    engine.GET("/logout", r.handler.Logout)

    engine.POST("/ws/createRoom", r.wsHandler.CreateRoom)
    engine.GET("/ws/joinRoom/:roomId", r.wsHandler.JoinRoom)
}

WebSocket处理函数

func (h *Handler) JoinRoom(c *gin.Context) {
    claims := c.Request.Context().Value("jwt").(models.Claims) //无法找到"jwt"对应的值
    fmt.Println(claims.ID, claims.Name)
    cookie, err := c.Cookie("chartJWT") //始终报错无Cookie
    if err != nil {
        fmt.Printf("no cookie, error:%v\n", err)
    }
    fmt.Printf("cookie: %+v\n", cookie)
    conn, err := upgrader.Upgrade(c.Writer, c.Request, nil)
    if err != nil {
        c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
        return
    }
}

认证中间件

func (h *handler) VerifyUser() gin.HandlerFunc {
    return func(c *gin.Context) {
        notAuth := []string{"/signup", "/signin"}
        requestPath := c.Request.URL.Path

        for _, val := range notAuth {
            if val == requestPath {
                c.Next()
                return
            }
        }

        token, err := c.Cookie("chartJWT")
        if err != nil {
            c.Redirect(http.StatusPermanentRedirect, signinPage)
        }

        claims, ok := validateToken(token)
        if !ok {
            c.JSON(http.StatusBadRequest, gin.H{"error": errors.New("invalid token")})
            return
        }

        c.Request = c.Request.WithContext(context.WithValue(c.Request.Context(), "jwt", *claims))

        c.Next()
    }
}

问题根因与解决

排查后确认,问题核心原因是Postman中WebSocket请求的Cookie配置错误,导致认证中间件无法读取到chartJWT Cookie,进而无法将JWT解析后的Claims注入请求上下文,最终在WebSocket处理函数中无法获取到认证信息。修正Postman的Cookie配置后,WebSocket接口即可正常通过认证并完成协议升级。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 19:28:11