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

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

问题描述

我在 Rails 中遇到了一些关于 Authenticity Token 的问题,就像我现在遇到的很多次一样.

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,将其与会话中存储的进行比较,如果匹配,则允许请求继续.

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天全站免登陆