[英]Gorilla CSRF - Forbidden - CSRF token invalid - fails when there are two forms
I'm adding in CSRF token validation and I'm running into a problem where I have two forms on a page and one of them will submit successfully and the other will not.我正在添加 CSRF 令牌验证,我遇到了一个问题,我在一个页面上有两个 forms,其中一个将成功提交,另一个不会。 I'm not doing AJAX requests, I'm simply using hidden input fields.
我不是在做 AJAX 请求,我只是在使用隐藏的输入字段。 If I submit the form when it is the only one on the page, it submits without issue.
如果我在页面上只有表单时提交表单,则它会毫无问题地提交。 If I submit it on a page with more than one form, it fails.
如果我在包含多个表单的页面上提交它,它会失败。
Below is the template code for my two forms下面是我的两个 forms 的模板代码
{{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>
And this is what the generated HTML looks like.这就是生成的 HTML 的样子。 Both appear to be valid.
两者似乎都是有效的。
When I click the "Logout" button though, I get the Forbidden - CSRF token invalid
error, but clicking the create input value in the second form always works.但是,当我单击“注销”按钮时,我得到了
Forbidden - CSRF token invalid
错误,但是单击第二种形式的创建输入值总是有效的。
The logout button is correctly validated when I attempt to use it on the home page which is "/admin/" but it does not work on any of the other pages "/admin/snippet/:id" or "/admin/snippet/create".当我尝试在主页“/admin/”上使用它时,注销按钮得到了正确验证,但它在任何其他页面“/admin/snippet/:id”或“/admin/snippet/”上都不起作用创造”。 The Logout button is part of a base template, so it appears on every page, so there shouldn't be anything different in how it appears on any page.
注销按钮是基本模板的一部分,因此它出现在每个页面上,因此它在任何页面上的显示方式应该没有什么不同。
I've read other SO posts about multiple forms & CSRF tokens on a page and I understand there should be no issue with multiple forms with the same information as long as you have each one in it's own form, it should be fine.我已经在页面上阅读了有关多个 forms 和 CSRF 令牌的其他 SO 帖子,并且我知道多个具有相同信息的 forms 应该没有问题,只要您每个都有自己的形式,应该没问题。 So I am not sure where I am going wrong.
所以我不确定我哪里出错了。
I found the issue.我发现了这个问题。 Currently the way that gorilla/csrf works, it does not like creating the masked token from one path and then sending that token off to another path.
目前 gorilla/csrf 的工作方式,它不喜欢从一个路径创建掩码令牌,然后将该令牌发送到另一条路径。 So in my situation, going from
/admin/snippet/create
to /admin/logout
threw an error because it was expecting the path for the token to be /admin/snippet/<something>
and so it threw an error.因此,在我的情况下,从
/admin/snippet/create
到/admin/logout
会引发错误,因为它期望令牌的路径为/admin/snippet/<something>
,因此会引发错误。
This issue has been addressed in this PR: https://github.com/gorilla/csrf/pull/147 and essentially the solution is to set the default path yourself to something which all of your routes will contain, so in my case that was /admin
此问题已在此 PR 中得到解决: https://github.com/gorilla/csrf/pull/147基本上解决方案是自己将默认路径设置为所有路由都将包含的内容,所以在我的情况下是
/admin
This is what my CSRF declaration looks like now in main.go
这就是我的 CSRF 声明现在在
main.go
中的样子
var csrfMiddleWare = csrf.Protect(
[]byte("<put your 32 character key here>"),
csrf.Path("/admin"),
csrf.Secure(false),
)
A note, if you had this issue and then apply this fix and it doesn't resolve the problem, trying testing in a separate browser as there may be some caching issues.请注意,如果您遇到此问题,然后应用此修复程序并不能解决问题,请尝试在单独的浏览器中进行测试,因为可能存在一些缓存问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.