英文:
Can't stop a middleware chain in Go/Gin
问题
我想在继续处理请求之前检查会话,并且我有一个中间件来检查会话。这是端点:
profile.Use(session.CheckSession())
profile.GET("/:pid", func(c *gin.Context) {
fmt.Println("Hit :pid")
c.File("../../html/profile.html")
})
这是CheckSession()
中间件,目前值是占位符:
func CheckSession() gin.HandlerFunc {
return func(c *gin.Context) {
session := sessions.Default(c)
userID := session.Get("user_id")
firstName := session.Get("firstname")
lastName := session.Get("lastname")
if userID == nil || firstName == nil || lastName == nil {
fmt.Println("No session")
c.Redirect(http.StatusSeeOther, "/sign-in")
return
}
fmt.Println("Hit c.Next()")
c.Next()
}
}
首先,我访问了"/"
路由,它重定向到/profile/:pid
端点,如果会话无效,则重定向到/sign-in
端点。我被重新路由到/sign-in
端点,但/profile/:pid
端点仍然执行完毕,即使从未调用c.Next()
。
尝试将它们放在if-else
块中,以确保只执行c.Redirect()
和c.Next()
中的一个,但函数仍然通过,并且链没有停止。
英文:
I want to check session before continuing with a request and I have a middleware to check that session. This is the endpoint:
profile.Use(session.CheckSession())
profile.GET("/:pid", func(c *gin.Context) {
fmt.Println("Hit :pid")
c.File("../../html/profile.html")
})
And this is the CheckSession()
middleware, values are placeholders atm:
func CheckSession() gin.HandlerFunc {
return func(c *gin.Context) {
session := sessions.Default(c)
userID := session.Get("user_id")
firstName := session.Get("firstname")
lastName := session.Get("lastname")
if userID == nil || firstName == nil || lastName == nil {
fmt.Println("No session")
c.Redirect(http.StatusSeeOther, "/sign-in")
return
}
fmt.Println("Hit c.Next()")
c.Next()
}
}
At first, I hit "/"
route, which redirects to /profile/:pid
endpoint, which redirects to /sign-in
endpoint in case of 'invalid' session. I get re-routed to the /sign-in
endpoint, but the /profile/:pid
endpoint still finishes execution, even without hitting c.Next()
ever
Tried putting them in if-else
blocks to make sure only one of c.Redirect()
and c.Next()
was being executed and so was happening, yet function was still passed and the chain didn't stop.
答案1
得分: 0
错误是由于没有手动中止中间件链引起的。
c.Redirect()
不会停止中间件链,你应该手动调用 c.Abort()
来阻止执行剩余的处理程序。
c.Abort()
工具提示:
>Abort 防止待处理程序被调用。请注意,这不会停止当前处理程序的执行。假设你有一个授权中间件,用于验证当前请求是否经过授权。如果授权失败(例如密码不匹配),调用 Abort 来确保不会调用此请求的剩余处理程序。
英文:
The error was caused by not aborting middleware chain manually.
c.Redirect()
doesn't stop the middleware chain, you should manually call c.Abort()
to prevent execution of the remaining handlers.
c.Abort()
Tooltip:
>Abort prevents pending handlers from being called. Note that this will not stop the current handler. Let's say you have an authorization middleware that validates that the current request is authorized. If the authorization fails (ex: the password does not match), call Abort to ensure the remaining handlers for this request are not called.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论