Gorilla Websocket结合Cookie-JWT认证失败问题求助
我尝试使用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
相关产品推荐
相关产品推荐

