跨域请求攻击(CSRF)

中间件 csrf 用于为 Macaron 实例 生成和验证 CSRF 令牌。

下载安装

  1. go get github.com/go-macaron/csrf

使用示例

想要使用该中间件,您必须同时使用 session 中间件。

  1. package main
  2.  
  3. import (
  4. "github.com/go-macaron/csrf"
  5. "github.com/go-macaron/session"
  6. "gopkg.in/macaron.v1"
  7. )
  8.  
  9. func main() {
  10. m := macaron.Classic()
  11. m.Use(macaron.Renderer())
  12. m.Use(session.Sessioner())
  13. m.Use(csrf.Csrfer())
  14.  
  15. // 模拟验证过程,判断 session 中是否存在 uid 数据。
  16. // 若不存在,则跳转到一个生成 CSRF 的页面。
  17. m.Get("/", func(ctx *macaron.Context, sess session.Store) {
  18. if sess.Get("uid") == nil {
  19. ctx.Redirect("/login")
  20. return
  21. }
  22. ctx.Redirect("/protected")
  23. })
  24.  
  25. // 设置 session 中的 uid 数据。
  26. m.Get("/login", func(ctx *macaron.Context, sess session.Store) {
  27. sess.Set("uid", 123456)
  28. ctx.Redirect("/")
  29. })
  30.  
  31. // 渲染一个需要验证的表单,并传递 CSRF 令牌到表单中。
  32. m.Get("/protected", func(ctx *macaron.Context, sess session.Store, x csrf.CSRF) {
  33. if sess.Get("uid") == nil {
  34. ctx.Redirect("/login", 401)
  35. return
  36. }
  37.  
  38. ctx.Data["csrf_token"] = x.GetToken()
  39. ctx.HTML(200, "protected")
  40. })
  41.  
  42. // 验证 CSRF 令牌。
  43. m.Post("/protected", csrf.Validate, func(ctx *macaron.Context, sess session.Store) {
  44. if sess.Get("uid") != nil {
  45. ctx.RenderData(200, []byte("You submitted a valid token"))
  46. return
  47. }
  48. ctx.Redirect("/login", 401)
  49. })
  50.  
  51. m.Run()
  52. }
  1. <!-- templates/protected.tmpl -->
  2. <form action="/protected" method="post">
  3. <input type="hidden" name="_csrf" value="{{.csrf_token}}">
  4. <button>提交</button>
  5. </form>

自定义选项

该服务允许接受一个参数来进行自定义选项(csrf.Options):

  1. // ...
  2. m.Use(csrf.Csrfer(csrf.Options{
  3. // 用于生成令牌的全局秘钥,默认为随机字符串
  4. Secret: "mysecret",
  5. // 用于传递令牌的 HTTP 请求头信息字段,默认为 "X-CSRFToken"
  6. Header: "X-CSRFToken",
  7. // 用于传递令牌的表单字段名,默认为 "_csrf"
  8. Form: "_csrf",
  9. // 用于传递令牌的 Cookie 名称,默认为 "_csrf"
  10. Cookie: "_csrf",
  11. // Cookie 设置路径,默认为 "/"
  12. CookiePath: "/",
  13. // 用于保存用户 ID 的 session 名称,默认为 "uid"
  14. SessionKey: "uid",
  15. // 用于指定是否将令牌设置到响应的头信息中,默认为 false
  16. SetHeader: false,
  17. // 用于指定是否将令牌设置到响应的 Cookie 中,默认为 false
  18. SetCookie: false,
  19. // 用于指定是否要求只有使用 HTTPS 时才设置 Cookie,默认为 false
  20. Secure: false,
  21. // 用于禁止请求头信息中包括 Origin 字段,默认为 false
  22. Origin: false,
  23. // 错误处理函数,默认为简单的错误输出
  24. ErrorFunc: func(w http.ResponseWriter) {
  25. http.Error(w, "Invalid csrf token.", http.StatusBadRequest)
  26. },
  27. }))
  28. // ...