Macaron Documentation
  • Welcome
  • Starter Guide
  • Core Concepts
  • Core Services
  • Custom Services
  • Middlewares
    • Routing
    • Templating
    • Gzip
    • Localization
    • Data Binding and Validation
    • Cache
    • Captcha
    • Session
    • Cross-Site Request Forgery
    • Embed Binary Data
    • Serving Multiple Sites
  • FAQs
  • 简体中文
    • 初学者指南
    • 核心概念
    • 核心服务
    • 自定义服务
    • 中间件和辅助模块
      • 路由模块
      • 模板引擎
      • Gzip 压缩
      • 应用本地化
      • 数据绑定与验证
      • 缓存管理(Cache)
      • 验证码服务
      • 会话管理(Session)
      • 跨域请求攻击(CSRF)
      • 嵌入二进制数据
      • 服务多个站点
    • 常见问题
Powered by GitBook
On this page
  • 下载安装
  • 使用示例
  • 自定义选项

Was this helpful?

  1. 简体中文
  2. 中间件和辅助模块

跨域请求攻击(CSRF)

Previous会话管理(Session)Next嵌入二进制数据

Last updated 5 years ago

Was this helpful?

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

下载安装

go get github.com/go-macaron/csrf

使用示例

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

package main

import (
    "github.com/go-macaron/csrf"
    "github.com/go-macaron/session"
    "gopkg.in/macaron.v1"
)

func main() {
    m := macaron.Classic()
    m.Use(macaron.Renderer())
    m.Use(session.Sessioner())
    m.Use(csrf.Csrfer())

    // 模拟验证过程,判断 session 中是否存在 uid 数据。
    // 若不存在,则跳转到一个生成 CSRF 的页面。
    m.Get("/", func(ctx *macaron.Context, sess session.Store) {
        if sess.Get("uid") == nil {
            ctx.Redirect("/login")
            return
        }
        ctx.Redirect("/protected")
    })

    // 设置 session 中的 uid 数据。
    m.Get("/login", func(ctx *macaron.Context, sess session.Store) {
        sess.Set("uid", 123456)
        ctx.Redirect("/")
    })

    // 渲染一个需要验证的表单,并传递 CSRF 令牌到表单中。
    m.Get("/protected", func(ctx *macaron.Context, sess session.Store, x csrf.CSRF) {
        if sess.Get("uid") == nil {
            ctx.Redirect("/login", 401)
            return
        }

        ctx.Data["csrf_token"] = x.GetToken()
        ctx.HTML(200, "protected")
    })

    // 验证 CSRF 令牌。
    m.Post("/protected", csrf.Validate, func(ctx *macaron.Context, sess session.Store) {
        if sess.Get("uid") != nil {
            ctx.RenderData(200, []byte("You submitted a valid token"))
            return
        }
        ctx.Redirect("/login", 401)
    })

    m.Run()
}
<!-- templates/protected.tmpl -->
<form action="/protected" method="post">
    <input type="hidden" name="_csrf" value="{{.csrf_token}}">
    <button>提交</button>
</form>

自定义选项

// ...
m.Use(csrf.Csrfer(csrf.Options{
    // 用于生成令牌的全局秘钥,默认为随机字符串
    Secret:        "mysecret",
    // 用于传递令牌的 HTTP 请求头信息字段,默认为 "X-CSRFToken"
    Header:        "X-CSRFToken",
    // 用于传递令牌的表单字段名,默认为 "_csrf"
    Form:        "_csrf",
    // 用于传递令牌的 Cookie 名称,默认为 "_csrf"
    Cookie:        "_csrf",
    // Cookie 设置路径,默认为 "/"
    CookiePath:    "/",
    // 用于保存用户 ID 的 session 名称,默认为 "uid"
    SessionKey:    "uid",
    // 用于指定是否将令牌设置到响应的头信息中,默认为 false
    SetHeader:    false,
    // 用于指定是否将令牌设置到响应的 Cookie 中,默认为 false
    SetCookie:  false,
    // 用于指定是否要求只有使用 HTTPS 时才设置 Cookie,默认为 false
    Secure:     false,
    // 用于禁止请求头信息中包括 Origin 字段,默认为 false
    Origin:     false,
    // 错误处理函数,默认为简单的错误输出
    ErrorFunc:  func(w http.ResponseWriter) {
        http.Error(w, "Invalid csrf token.", http.StatusBadRequest)
    },
    }))
// ...

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

csrf.Options
GitHub
API 文档
session
Macaron 实例