Understanding the Rails Authenticity Token

摘要

本文将介绍Rails中的Authenticity Token的作用以及原理。Authenticity Token用于防止跨站请求伪造(Cross-Site Request Forgery, CSRF)攻击。

内容

Rails中的Authenticity Token是用来保证表单提交请求来自于当前网站,而不是其他网站或者应用程序。

当用户访问一个创建、更新或删除资源的表单时,Rails应用程序会自动生成一个随机的authenticity_token,并将其存储在session中,并将其放入表单的隐藏字段中。当用户提交表单时,Rails会查找authenticity_token并将其与存储在session中的值进行比较,如果匹配则允许请求继续执行。

authenticity_token是存储在session中的,客户端无法知道其值。这样可以防止人们在没有在Rails应用程序内查看表单的情况下提交表单。想象一下,你正在使用A服务,你已经登录并一切正常。现在,想象一下你去使用B服务,并且你看到了一张你喜欢的图片,点击图片查看更大尺寸。现在,如果B服务中有一些恶意代码,它可能发送一个请求到你已登录的A服务,请求删除你的账户,如发送请求到http://serviceA.example/close_account。这就是所谓的CSRF(跨站请求伪造)攻击。

如果服务A使用authenticity_token,这种攻击就不再适用,因为服务B的请求不会包含正确的authenticity_token,请求将被拒绝。

Rails的API文档中描述了有关meta标签的详细信息:

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

需要注意的是,Rails只会验证非幂等请求(POST、PUT/PATCH和DELETE)。GET请求不会进行authenticity_token的验证。为什么呢?因为HTTP规范规定GET请求是幂等的,并且不应该在服务器端创建、更改或删除资源,请求应该是幂等的(如果您多次运行相同的命令,每次应该得到相同的结果)。

实际的实现比上面描述的要复杂一些,为了提供更好的安全性,Rails不会在每个表单中使用相同的存储的token。它也不会每次生成一个不同的token并将其存储起来。它会生成并存储一个加密哈希值,称为session,并在每次呈现页面时发放与存储的token相匹配的新的cryptographic token。具体的实现细节请参考request_forgery_protection.rb。

总结

在Rails中,使用authenticity_token来保护非幂等方法(POST、PUT/PATCH和DELETE)。同时,确保不允许任何可能修改服务器上资源的GET请求。

文章内容如上,详细介绍了Rails中的Authenticity Token的作用和原理。希望对你有所帮助!



相关文章推荐