小编典典

了解 Rails 真实性令牌

all

我遇到了一些关于 Rails 中的 Authenticity Token 的问题。

我真的很想了解 Authenticity 令牌。

您是否有关于此主题的完整信息来源,或者您会花时间在这里详细解释吗?


阅读 91

收藏
2022-02-28

共1个答案

小编典典

发生什么了

当用户查看表单以创建、更新或销毁资源时,Rails 应用程序会创建一个 random
authenticity_token,将此令牌存储在会话中,并将其放置在表单的隐藏字段中。当用户提交表单时,Rails
会查找authenticity_token,并将其与存储在会话中的表单进行比较,如果匹配,则允许继续请求。

为什么会发生

由于真实性令牌存储在会话中,客户端无法知道其值。这可以防止人们在没有查看该应用程序本身的表单的情况下向 Rails
应用程序提交表单。想象一下,您正在使用服务
A,您已登录该服务并且一切正常。现在想象一下你去使用服务B,你看到了一张你喜欢的图片,然后点击图片查看更大尺寸的图片。现在,如果服务 B
中有一些恶意代码,它可能会向服务 A(您已登录)发送请求,并通过向http://serviceA.com/close_account.
这就是所谓的CSRF(跨站请求伪造)

如果服务 A 正在使用真实性令牌,则此攻击向量不再适用,因为来自服务 B 的请求将不包含正确的真实性令牌,并且不会被允许继续。

API
文档
描述了有关元标记的详细信息:

CSRF 保护使用该方法打开,该protect_from_forgery方法检查令牌并在它与预期不匹配时重置会话。默认情况下,会为新的 Rails
应用程序生成对该方法的调用。token
参数authenticity_token默认命名。必须将此标记的名称和值添加到通过包含csrf_meta_tags在 HTML
头部中来呈现表单的每个布局中。

笔记

请记住,Rails 仅验证非幂等方法(POST、PUT/PATCH 和 DELETE)。不检查 GET 请求的真实性令牌。为什么?因为 HTTP 规范规定
GET 请求是幂等的,不应 服务器上创建、更改或销毁资源,并且请求应该是幂等的(如果多次运行相同的命令,则每次都应该得到相同的结果)。

此外,真正的实现比开始时定义的要复杂一些,以确保更好的安全性。Rails
不会为每个表单颁发相同的存储令牌。它也不会每次都生成和存储不同的令牌。它在会话中生成并存储一个加密哈希,并在每次呈现页面时发布新的加密令牌,这些令牌可以与存储的令牌进行匹配。请参阅request_forgery_protection.rb

课程

用于authenticity_token保护您的非幂等方法(POST、PUT/PATCH 和 DELETE)。还要确保不允许任何可能修改服务器上资源的
GET 请求。


编辑: 检查@erturne关于 GET
请求是幂等的评论。他以比我在这里所做的更好的方式解释它。

2022-02-28