Rails 4 真实性令牌 - 在标题和表单隐藏输入中?
Posted
技术标签:
【中文标题】Rails 4 真实性令牌 - 在标题和表单隐藏输入中?【英文标题】:Rails 4 authenticity token - both in header and form hidden input? 【发布时间】:2016-08-19 11:15:14 【问题描述】:我正在尝试在 Rails 中获得整页缓存,但我在 CSRF 方面遇到了很大的障碍——或者可能只是我对它的理解。我目前将form_authenticity_token
字符串存储在一个 cookie 中,JS 可以使用该 cookie 访问和重写标题标签。
我在生成的 html 中有两个地方可以找到标记:
1) 在头脑中
<meta name="csrf-token" content="[hash]">
2) 在表单的隐藏输入元素内
<input type="hidden" name="authenticity_token" value="[different hash]">
如前所述,这些哈希值彼此不同(在未启用缓存的开发模式下)。为什么它们不同?为什么我可以删除头部元标记并单独保留表单输入并且允许请求?然而,当我删除表单输入标签并留下标题时,请求被拒绝?
实际上这意味着 head 标签是无用的,不是吗?我可以将表单输入标签重写为我的 cookie 中的值,就像我对标题标签所做的那样,但由于它们彼此不同,我对最终结果可能意味着什么持谨慎态度,尤其是在涉及整页缓存时.
应用控制器包含:
protect_from_forgery with: :exception
before_filter :csrf_cookie
def csrf_cookie
cookies['authenticity-token'.freeze] =
value: form_authenticity_token,
expires: 1.day.from_now,
secure: (Rails.env.staging? || Rails.env.production?)
end
【问题讨论】:
【参考方案1】:在另一个问题上浏览 SO led me to the answer。简而言之,Rails 通过自动将 CSRF 令牌插入 ajax 请求来帮助 jQuery 用户。它在元标记中查找它。
因此,在表单中包含 CSRF 令牌对于提交 POST 请求并将其放在头部很有用,这对于节省 ajax 请求的时间/精力/错误很有用。
也许在两者中都有它是好的,因为当没有表单存在时您可能想要执行 ajax 请求。如果有一个表单并且 javascript 被禁用,将它放在标头中不会给任何人带来任何好处,因为它不会包含在 POST 请求中。
至于为什么它们不同,我只能猜测它与生成时的算法有关......但这既不是这里也不是那里,因为两个令牌都起作用。
【讨论】:
以上是关于Rails 4 真实性令牌 - 在标题和表单隐藏输入中?的主要内容,如果未能解决你的问题,请参考以下文章
如何在rails中处理来自应用程序控制器的无效真实性令牌json请求