gin-csrf icon indicating copy to clipboard operation
gin-csrf copied to clipboard

Is there a way to avoid verification

Open hongjinlin opened this issue 7 years ago • 8 comments

I have a scenario that needs to receive a third-party post. Thanks!

hongjinlin avatar Mar 21 '18 02:03 hongjinlin

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

}

hongjinlin avatar Mar 21 '18 03:03 hongjinlin

"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)
...

delphinus avatar Mar 21 '18 09:03 delphinus

@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.

utrack avatar Mar 21 '18 09:03 utrack

Thank you for your answer @delphinus @utrack I add IgnoreRoute config in my fork https://github.com/hongjinlin/gin-csrf.git

hongjinlin avatar Apr 03 '18 06:04 hongjinlin

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.

delphinus avatar Apr 04 '18 07:04 delphinus

I like your solution more @delphinus. Pushing some value to the ctx and then rechecking it should do the trick.

utrack avatar Apr 04 '18 07:04 utrack

Maybe you are right, but in our scenario csrf middleware is global, it is not realistic to modify other routes now.

hongjinlin avatar Apr 04 '18 08:04 hongjinlin

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?

delphinus avatar Apr 04 '18 14:04 delphinus