csrf

csrf 中间件为 Flame 实例提供 CSRF 令牌的生成和验证服务,该中间件依赖于 session 中间件。

你可以在 GitHub在新窗口打开 上阅读该中间件的源码或通过 pkg.go.dev在新窗口打开 查看 API 文档。

下载安装

go get github.com/flamego/csrf

用法示例

注意

本小结仅展示 csrf 中间件的相关用法,示例中的用户验证方案绝不可以直接被用于生产环境。

csrf.Csrfer在新窗口打开 可以配合 csrf.Options在新窗口打开 对中间件进行配置,并使用 csrf.Validate在新窗口打开 来进行 CSRF 令牌的验证:

package main

import (
	"net/http"

	"github.com/flamego/csrf"
	"github.com/flamego/flamego"
	"github.com/flamego/session"
	"github.com/flamego/template"
)

func main() {
	f := flamego.Classic()
	f.Use(template.Templater())
	f.Use(session.Sessioner())
	f.Use(csrf.Csrfer())

	// 模拟会话认证,若 userID 存在则重定向到包含 CSRF 令牌的表单页面
	f.Get("/", func(c flamego.Context, s session.Session) {
		if s.Get("userID") == nil {
			c.Redirect("/login")
			return
		}
		c.Redirect("/protected")
	})

	// 设置会话的 uid
	f.Get("/login", func(c flamego.Context, s session.Session) {
		s.Set("userID", 123)
		c.Redirect("/")
	})

	// 使用 x.Token() 将 CSRF 令牌渲染到模板中
	f.Get("/protected", func(c flamego.Context, s session.Session, x csrf.CSRF, t template.Template, data template.Data) {
		if s.Get("userID") == nil {
			c.Redirect("/login", http.StatusUnauthorized)
			return
		}

		// 传递令牌到被渲染的模板
		data["CSRFToken"] = x.Token()
		t.HTML(http.StatusOK, "protected")
	})

	// 应用 CSRF 验证
	f.Post("/protected", csrf.Validate, func(c flamego.Context, s session.Session, t template.Template) {
		if s.Get("userID") != nil {
			c.ResponseWriter().Write([]byte("You submitted with a valid CSRF token"))
			return
		}
		c.Redirect("/login", http.StatusUnauthorized)
	})

	f.Run()
}








































 
 



 
 








<form action="/protected" method="POST">
  <input type="hidden" name="_csrf" value="{{.CSRFToken}}">
  <button>Submit</button>
</form>