2

我有以下 Gin 中间件:

func CheckAppId(appC *core.Context) gin.HandlerFunc {
    return func(c *gin.Context) {
        //get Basic Auth credentials
        appId, token, _ := c.Request.BasicAuth()

        if appId == "" {
            c.JSON(http.StatusOK, gin.H{"code": "MISSING_APP_ID", "message": "Your request is missing an application id"})
            return //this is being ignored???
        }

        c.Next() //this still gets hit
    }
}

但是如果appId == ""JSON 被返回c.Next()并被执行。这是预期的行为吗?

编辑 我认为问题已被出售,但似乎正在发生同样的事情。我现在有:

func CheckAppId(appC *core.Context) gin.HandlerFunc {
    return func(c *gin.Context) {
        //get Basic Auth credentials
        appId, token, _ := c.Request.BasicAuth()

        if appId == "" {
            //I'm getting this JSON in the response
            c.JSON(http.StatusOK, gin.H{"code": "MISSING_APP_ID", "message": "Your request is missing an application id"})
            c.Abort()
        }

        //find app_id in database
        app := core.App{}
        err := appC.Database.C("apps").Find(bson.M{"id" : appId}).One(&app)
        if err != nil { //no app found
            //and I'm getting this JSON in the response
            c.JSON(http.StatusOK, gin.H{"code": "INVALID_APP_ID", "message": "The application id provided could not be found"})
            c.Abort()
        }

        c.Next()
    }
}

在对 API 的调用中,我同时收到“MISSING_APP_ID”Json 和“INVALID_APP_ID”Json

4

2 回答 2

5

查看 Gin API 文档,您需要调用context.Abort()而不是从您的方法返回。

Abort 停止系统继续调用链中的挂起处理程序。假设您有一个授权中间件,如果授权失败(密码不匹配),它会验证请求是否被授权。应该调用此方法 (Abort()) 以停止实际处理程序的执行。

所以在你的具体情况下

if appId == "" {
    c.JSON(http.StatusOK, gin.H{"code": "MISSING_APP_ID", "message": "Your request is missing an application id"})
    c.Abort()
    return
}
于 2015-09-08T21:00:39.477 回答
4

TL;博士

你需要做:

if condition {
  c.Abort()
} else {
  c.Next()
}

解释

(注意:这建立在@Landers 的回答之上)

c.Abort()只是设置一些内部标志,以某种方式标记上下文,指示异常终止。这是有道理的,它是一个不返回任何内容的无参数方法,所以你只是因为它的副作用而调用它。

同样的事情c.Next()

由于 go 的控制流(没有异常或跳转),很明显这两种方法不会立即采取任何行动,而是为下一阶段“搭建舞台”,想象一下调用您的CheckAppIdfunc 的 Gins 代码:

// gin code
doStuff()
ctx := getContext()

// this is your CheckAppId
nextAction := FindAction()
nextAction(&ctx)

// here the context is evaluated to see if you either abort or continue.
checkContextStatus(&ctx)

因此,如果您正在调用c.Abort(),然后c.Next()您将覆盖中止指示。

于 2015-09-09T13:29:46.437 回答