如何解决Gorilla CSRF - Forbidden - CSRF 令牌无效 - 当有两种形式时失败
我正在添加 CSRF 令牌验证,但遇到了一个问题,我在页面上有两个表单,其中一个将成功提交,而另一个则不会。我不是在做 AJAX 请求,我只是在使用隐藏的输入字段。如果我在页面上只有表单时提交表单,则提交没有问题。如果我在一个包含多个表单的页面上提交它,它会失败。
下面是我的两个表单的模板代码
{{if .IsAuthenticated}}
<form action='/admin/logout' method='POST'>
<button>logout</button>
{{.CsrfField}}
</form>
{{end}}
<form action='/admin/stuff/create' method='POST'>
{{with .Form}}
<div>
<label>Title:</label>
<input type='text' name='title' value='{{.Get "title"}}'>
</div>
<div>
<input type='submit' value='Publish stuff'>
</div>
{{end}}
{{.CsrfField}}
</form>
这就是生成的 HTML 的样子。两者似乎都有效。
不过,当我单击“注销”按钮时,出现 Forbidden - CSRF token invalid
错误,但单击第二个表单中的创建输入值始终有效。
当我尝试在主页“/admin/”上使用注销按钮时正确验证了它,但它在任何其他页面“/admin/snippet/:id”或“/admin”上不起作用/片段/创建”。 “注销”按钮是基本模板的一部分,因此它出现在每个页面上,因此它在任何页面上的显示方式应该没有任何不同。
我在页面上阅读了有关多个表单和 CSRF 令牌的其他 SO 帖子,我理解具有相同信息的多个表单应该没有问题,只要每个表单都有自己的表单,应该没问题.所以我不确定我哪里出错了。
解决方法
我发现了这个问题。目前 gorilla/csrf 的工作方式是,它不喜欢从一个路径创建掩码令牌,然后将该令牌发送到另一条路径。因此,在我的情况下,从 /admin/snippet/create
到 /admin/logout
会引发错误,因为它期望令牌的路径为 /admin/snippet/<something>
,因此它引发了错误。
此问题已在此 PR 中解决:https://github.com/gorilla/csrf/pull/147 基本上解决方案是自己将默认路径设置为所有路由都将包含的内容,因此在我的情况下为 /admin
这就是我现在在 main.go
var csrfMiddleWare = csrf.Protect(
[]byte("<put your 32 character key here>"),csrf.Path("/admin"),csrf.Secure(false),)
请注意,如果您遇到此问题,然后应用此修复程序但它没有解决问题,请尝试在单独的浏览器中进行测试,因为可能存在一些缓存问题。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。