中间件 csrf 用于为 Macaron 实例 生成和验证 CSRF 令牌。
go get github.com/go-macaron/csrf
想要使用该中间件,您必须同时使用 session 中间件。
package mainimport ("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>
该服务允许接受一个参数来进行自定义选项(csrf.Options
):
// ...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",// 用于指定是否将令牌设置到响应的头信息中,默认为 falseSetHeader: false,// 用于指定是否将令牌设置到响应的 Cookie 中,默认为 falseSetCookie: false,// 用于指定是否要求只有使用 HTTPS 时才设置 Cookie,默认为 falseSecure: false,// 用于禁止请求头信息中包括 Origin 字段,默认为 falseOrigin: false,// 错误处理函数,默认为简单的错误输出ErrorFunc: func(w http.ResponseWriter) {http.Error(w, "Invalid csrf token.", http.StatusBadRequest)},}))// ...