我在Rails中遇到了一些关于真实性令牌的问题,就像我现在遇到的很多次一样
但我真的不想只是解决这个问题然后继续。我真的很想了解真实性令牌。
好吧,我的问题是,你有关于这个主题的完整信息来源吗,或者你会花时间在这里详细解释吗
发生了什么
当用户查看表单以创建、更新或销毁资源时,Rails应用程序会创建一个随机的authenticity\u令牌,将该令牌存储在会话中,并将其放置在表单的隐藏字段中。当用户提交表单时,Rails会查找真实性\u令牌,将其与会话中存储的令牌进行比较,如果它们匹配,则允许继续请求
为什么会这样
由于真实性令牌存储在会话中,因此客户端无法知道其值。这可以防止人们在不查看Rails应用程序中的表单的情况下向Rails应用程序提交表单。
假设您正在使用服务A,您登录了该服务,并且一切正常。现在想象一下,您使用了服务B,看到了一张您喜欢的图片,然后按下图片查看更大的图片。现在,如果服务B中存在一些恶意代码,它可能会向服务a(您已登录)发送请求,并通过向http://serviceA.com/close_account。这就是所谓的CSRF(跨站点请求伪造)
如果服务A使用真实令牌,则该攻击向量不再适用,因为来自服务B的请求不包含正确的真实令牌,并且将不允许继续。
API文档描述了元标记的详细信息:
CSRF保护通过
防止伪造方法打开,
它会检查令牌,并在不匹配的情况下重置会话
这是意料之中的。为新Rails生成对该方法的调用
默认情况下,应用程序。
默认情况下,令牌参数名为authenticity\u token。名字
这个标记的值必须添加到每个呈现的布局中
通过在HTML头中包含csrf\u meta\u标记形成表单
注释
请记住,Rails只验证幂等方法(POST、PUT/PATCH和DELETE)。未检查GET请求的真实性令牌。为什么?因为HTTP规范规定GET请求是幂等的,并且应该而不是在服务器上创建、更改或销毁资源,并且请求应该是幂等的(如果多次运行同一命令,每次都应该得到相同的结果)
而且,真正的实现要比一开始定义的复杂一些,以确保更好的安全性。Rails不会对每个表单发出相同的存储令牌。它也不会每次生成和存储不同的令牌。它在会话中生成并存储加密哈希,并在每次呈现页面时发出新的加密令牌,这些令牌可以与存储的令牌匹配。请参阅request_forgery_protection.rb
课程
使用authenticity\u token保护非幂等方法(POST、PUT/PATCH和DELETE)。还要确保不允许任何可能修改服务器上资源的GET请求
编辑:检查@erturne关于GET请求是幂等的评论。他比我在这里解释得更好