Is there a way to avoid verification
I have a scenario that needs to receive a third-party post. Thanks!
not IgnoreMethods,but a router such as wechat := router.Group("/wechat") { wechatC := new(Wechat) wechat.POST("/callback", wechatC.Callback)//Normal verification wechat.POST("/message", wechatServerC.Message)//how to avoid verification
}
"avoid verification" means you want not to set CSRF protection to a certain path? gin can apply middlewares to the whole router, each group (path), or each endpoints.
mw := csrf.Middleware(csrf.Options{...})
r := gin.New()
r.POST("/need_not_to_protect", safeFunc)
r.POST("/need_to_protect", mw, dangerFunc)
// ...or...
r := gin.New()
rs := r.Group("/need_not_to_protect")
rs.POST("safe", safeFunc)
...
rd := r.Group("/need_to_protect", mw)
rs.POST("danger", dangerFunc)
...
@hongjinlin you can create two Groups, one of which would be protected and another one unprotected. Parts of their paths can overlap, so if you create two "/wechat" groups it won't be a problem - one group can use the middleware (i.e. be CSRF-protected) and one can do without the m/w.
Thank you for your answer @delphinus @utrack I add IgnoreRoute config in my fork https://github.com/hongjinlin/gin-csrf.git
I think this would be achieved by adding another middleware because the paths both in routing setting and in ignoreRoutes are duplicated.
By #10, you can use this feature with codes below...
mw := csrf.Middleware(csrf.Options{
Secret: ...,
IgnoreRoutes: []string{"/path/to/safe"},
})
r := gin.New()
rr := r.Group("/path/to", mw)
rr.POST("unsafe", foo.Unsafe)
rr.POST("safe", foo.Safe)
Then, if you want to change the path /path/to to /nice/path/to, you must change all codes that has /path/to.
mw := csrf.Middleware(csrf.Options{
Secret: ...,
IgnoreRoutes: []string{"/path/to/safe"}, // <- to change
})
...
rr := r.Group("/path/to", mw) // <- to change
In small apps, this is OK. But this is easy to mistake in huge apps that has multiple source files for routing.
So I suggest to use another middleware for this.
mw := csrf.Middleware(csrf.Options{
Secret: ...,
})
r := gin.New()
rr := r.Group("/path/to", mw)
rr.POST("unsafe", foo.Unsafe)
// ignore CSRF feature for this route only
rr.POST("safe", csrf.Ignore, foo.Safe)
How about this? @hongjinlin , @utrack I will push PR later for this implementation.
I like your solution more @delphinus. Pushing some value to the ctx and then rechecking it should do the trick.
Maybe you are right, but in our scenario csrf middleware is global, it is not realistic to modify other routes now.
I see... I have mistaken. Gin executes handlers from outer to inner, and the outer handler cannot distinguish inners. So, as @hongjinlin says, it is impossible for CSRF middleware to change its behavior according to inner middlewares including csrf.Ignore I illustrated above.
// in my plan...
rr := r.Use(csrf.Middleware())
rr.POST("/foo", csrf.Ignore, bar.Foo)
// and it executes in this order
// 1. csrf.Middleware()
// 2. csrf.Ignore
// 3. bar.Foo
//
// csrf.Ignore cannot change csrf.Middleware()'s behavior!!
I gave up ;( Anyone can know a good solution for this?