Revel框架默认不启用CSRF防护,需手动安装revel-csrf包(go get github.com/cbonello/revel-csrf)并在init()中将csrf.CSRFFilter插入Filter链,位置须在SessionFilter之后、ActionInvoker之前;前端表单和AJAX须显式传入名为csrf_token的字段值{{.csrf_token}},且app.secret必须为非空、固定、跨实例一致的字符串以确保token签名有效。

Revel框架默认不启用CSRF防护,必须手动引入第三方包并插入Filter链,否则所有POST/PUT/DELETE请求都裸奔。
revel-csrf包怎么装和注册
Revel本身没内置CSRF支持,得用社区维护的github.com/cbonello/revel-csrf。执行go get github.com/cbonello/revel-csrf后,在app/init.go的init()函数里把csrf.CSRFFilter加进Filter链——注意位置:它必须在SessionFilter之后、ActionInvoker之前,否则拿不到session里的token。
- 漏掉
SessionFilter前置会导致csrf_token为空 - 放在
ActionInvoker之后会跳过验证,形同虚设 - 别用
revel.InterceptorFilter包裹它——CSRF是全局请求级校验,不是Action级
前端表单和AJAX怎么传token
Revel的CSRF token通过模板变量{{ .csrf_token }}暴露,但只对渲染模板的Controller生效(即你得在Controller里显式调用renderArgs["csrf_token"] = csrf.Token(c),否则模板里取不到)。
- HTML表单必须加
<input type="hidden" name="csrf_token" value="{{ .csrf_token }}"> - AJAX请求得手动把
{{ .csrf_token }}塞进请求体(不是Header),字段名必须是csrf_token - 别指望自动注入——Revel没
@csrf这类Blade指令,全靠手写
为什么403了但token明明对得上
常见原因是token签名失效,根源在app.conf里app.secret配置。这个值是CSRF token签名密钥,开发时如果用默认值或空字符串,多个实例之间token无法互验;上线后若没统一配置,负载均衡下用户在A机器生成的token,到B机器就验不过。
- 检查
app.conf中app.secret是否为非空、固定、跨实例一致的字符串 - 别用
time.Now().String()之类动态值初始化secret - token有效期由session配置决定,不是CSRF包控制——改
session.expires才影响token寿命
最易忽略的是:Revel的CSRF token绑定的是session ID,不是用户ID。如果用户登出后session没销毁(比如只清了user数据没调c.Session.Clear()),旧token仍能通过验证——这会让“登出后重放攻击”成为可能。


















