了解Rails真实性令牌 [英] Understanding the Rails Authenticity Token

查看:109
本文介绍了了解Rails真实性令牌的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

正如我现在很多次一样,我遇到了一些与Rails中的真实性令牌有关的问题.

I am running into some issues regarding the Authenticity Token in Rails, as I have many times now.

但是我真的不想仅仅解决这个问题然后继续.我真的很想了解真实性令牌. 好吧,我的问题是,您是否有关于此主题的完整信息来源,或者您愿意花时间在此处进行详细说明?

But I really don't want to just solve this problem and go on. I would really like to understand the Authenticity token. Well, my question is, do you have some complete source of information on this subject or would you spend your time to explain in details here?

推荐答案

会发生什么

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

When the user views a form to create, update, or destroy a resource, the Rails app creates a random authenticity_token, stores this token in the session, and places it in a hidden field in the form. When the user submits the form, Rails looks for the authenticity_token, compares it to the one stored in the session, and if they match the request is allowed to continue.

为什么会发生

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

Since the authenticity token is stored in the session, the client cannot know its value. This prevents people from submitting forms to a Rails app without viewing the form within that app itself. Imagine that you are using service A, you logged into the service and everything is ok. Now imagine that you went to use service B, and you saw a picture you like, and pressed on the picture to view a larger size of it. Now, if some evil code was there at service B, it might send a request to service A (which you are logged into), and ask to delete your account, by sending a request to http://serviceA.com/close_account. This is what is known as CSRF (Cross Site Request Forgery).

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

If service A is using authenticity tokens, this attack vector is no longer applicable, since the request from service B would not contain the correct authenticity token, and will not be allowed to continue.

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

API docs describes details about meta tag:

CSRF保护通过protect_from_forgery方法打开, 它检查令牌并在会话不匹配时重置会话 是预期的.会为新的Rails生成对此方法的调用 默认情况下. 默认情况下,令牌参数的名称为authenticity_token.名字 并且此令牌的值必须添加到呈现的每个布局中 通过在HTML头中包含csrf_meta_tags来形成表格.

CSRF protection is turned on with the protect_from_forgery method, which checks the token and resets the session if it doesn't match what was expected. A call to this method is generated for new Rails applications by default. The token parameter is named authenticity_token by default. The name and value of this token must be added to every layout that renders forms by including csrf_meta_tags in the HTML head.

注释

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

Keep in mind, Rails only verifies not idempotent methods (POST, PUT/PATCH and DELETE). GET request are not checked for authenticity token. Why? because the HTTP specification states that GET requests is idempotent and should not create, alter, or destroy resources at the server, and the request should be idempotent (if you run the same command multiple times, you should get the same result every time).

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

Also the real implementation is a bit more complicated as defined in the beginning, ensuring better security. Rails does not issue the same stored token with every form. Neither does it generate and store a different token every time. It generates and stores a cryptographic hash in a session and issues new cryptographic tokens, which can be matched against the stored one, every time a page is rendered. See request_forgery_protection.rb.

经验教训

使用authenticity_token保护您的非幂等方法(POST,PUT/PATCH和DELETE).另外,请确保不允许任何可能修改服务器资源的GET请求.

Use authenticity_token to protect your not idempotent methods (POST, PUT/PATCH, and DELETE). Also make sure not to allow any GET requests that could potentially modify resources on the server.

编辑:检查 @erturne的评论关于GET请求是幂等的.他用比我在这里做的更好的方式解释了这一点.

Check the comment by @erturne regarding GET requests being idempotent. He explains it in a better way than I have done here.

这篇关于了解Rails真实性令牌的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆