第一部分
如果您通过 GET 参数、POST 数据或请求标头传递真实性令牌(POST/GET 参数在 Rails 中几乎相同),则完全没有区别。
让我们看看代码(不是我见过的最好的代码,但是......)
def verified_request?
!protect_against_forgery? || request.get? || request.head? ||
form_authenticity_token == params[request_forgery_protection_token] ||
form_authenticity_token == request.headers['X-CSRF-Token']
end
请求是否有效 if(以下任何一项)
protect_against_forgery?
是假的
- 请求是 GET
- 请求是 HEAD
- 参数中的令牌等于存储在会话中的一个
- 标头中的令牌等于存储在会话中的令牌
我应该添加该令牌为每个请求生成并存储在会话中以供以后检查(如果后续请求是 POST/PUT/PATCH/DELETE)
因此,正如您所见,两种传递真实性令牌的方式都是有效的。
第二部分
在 AJAX 中传递原始身份验证令牌是否危险?不,只要以表格形式传递它完全没有危险。为了进一步解释,我将在另一个 SO question 中引用一个很好的答案
为什么会这样:由于真实性令牌存储在会话中,客户端无法知道它的值。这可以防止人们在没有查看该应用程序本身的表单的情况下将表单提交到 Rails 应用程序。想象一下,您正在使用服务 A,您已登录该服务并且一切正常。现在假设你去使用服务 B,你看到了一张你喜欢的图片,并按下图片查看它的更大尺寸。现在,如果服务 B 中有一些恶意代码,它可能会向服务 A(您已登录)发送请求,并通过向
http://serviceA.com/close_account发送请求来要求删除您的帐户。这就是所谓的 CSRF(跨站点请求伪造)。
原始答案:https ://stackoverflow.com/a/1571900/2422778
我仍然认为这个问题是你的懒惰/缺乏耐心,因为我写的所有内容在 Rails Guides 和 Stack Overflow 上都有很好的解释。希望下次您在此处发布之前更加坚持寻找答案。
无论如何,我很高兴能帮上忙。