使用gqlgen与Gin时认证错误返回空响应问题求助
Gin+GraphQL认证中间件返回空响应及"missing response context"问题解决
当请求无有效Token时,预期返回403状态码,但实际返回空响应,同时出现以下错误提示:
missing response context
当前使用的认证中间件代码如下:
func (auth *Auth) Middleware() gin.HandlerFunc { return func(c *gin.Context) { _, err := auth.Validate(c.Request.Context(), c.Request) if (err != nil) { c.AbortWithError(http.StatusForbidden, err) return } c.Next() } }
在server.go中的使用方式:
func Register(config *viper.Viper, broker *broker.Broker, metrics *metrics.Metrics, clients *clients.Clients, auth *auth.Auth) { //... r.Use(auth.Middleware()) //... r.POST("/query", graphqlHandler(broker, clients, metrics)) r.GET("/query", graphqlHandler(broker, clients, metrics)) r.GET("/", playgroundHandler()) _ = r.Run() }
解决办法
问题根源在于c.AbortWithError仅将错误存入上下文,但不会主动向客户端发送响应内容。后续被终止的GraphQL handler尝试使用已中断的上下文时,就会抛出"missing response context"错误。
修改中间件,使用AbortWithStatusJSON直接返回带错误信息的403响应,同时终止请求链:
func (auth *Auth) Middleware() gin.HandlerFunc { return func(c *gin.Context) { _, err := auth.Validate(c.Request.Context(), c.Request) if err != nil { // 直接返回JSON格式的403错误响应 c.AbortWithStatusJSON(http.StatusForbidden, gin.H{ "error": "无效的Token", "detail": err.Error(), }) return } c.Next() } }
如果需要保留AbortWithError的错误记录逻辑,也可以在调用后手动发送响应:
func (auth *Auth) Middleware() gin.HandlerFunc { return func(c *gin.Context) { _, err := auth.Validate(c.Request.Context(), c.Request) if err != nil { c.AbortWithError(http.StatusForbidden, err) // 手动发送403响应 c.JSON(http.StatusForbidden, gin.H{"error": "无效的Token"}) return } c.Next() } }
两种方式都能确保在认证失败时主动返回403响应,避免后续GraphQL handler因上下文问题抛出错误。
内容的提问来源于stack exchange,提问作者Marcia Piccione
相关产品推荐
相关产品推荐

