Rails 4中secret_key_base的用途是什么


77

我是Rails 4的新手,并且不了解Rails 4中secret_key_baseunder的使用。config/secrets.yml您能解释一下这个概念吗?

此外,当我在生产环境中我的工作,我提示设置secret_keydevise.rbconfig.secret_keysecret_key_base。但是,我可以使用该rake secret命令生成一个新的机密。

开发和生产环境之间有什么区别?

secret_key当我secret_key_base每次添加新生成的内容时,它如何匹配新生成的内容?

如何通过其他服务器保护应用程序?


4
对于使用Ruby on Rails 5.2或更高版本的读者。secret_key_base仍在使用,但存储在其中config/credentials.yml.enc。该文件已加密。您可以在此处找到有关新凭证系统的更多信息,或运行rails credentials:help
3limin4t0r

Answers:


65

secret_token.rb文件的内容包括一个较长的随机字符串,该字符串用于验证已签名Cookie的完整性(例如,人们登录您的Web应用程序时的用户会话)。

文档说:

使用secret_token.rb初始化程序中现有的secret_key_base可以为在生产模式下运行Rails应用程序的任何用户设置SECRET_KEY_BASE环境变量。或者,您可以简单地将现有的secret_key_base从secret_token.rb初始化程序复制到生产部分下的secrets.yml中,替换为<%= ENV["SECRET_KEY_BASE"] %>

由于它是重要文件,并且不能将其放入.gitignore,因此使用env变量存储secret_key_base值被视为一种好习惯:

创建.env.powenv归档并将其存储为:

export SECRET_TOKEN="9489b3eee4eccf317ed77407553e8adc97baca7c74dc7ee33cd93e4c8b69477eea66eaedeb18af0be2679887c7c69c0a28c0fded0a71ea472a8c4laalal19cb"

然后在 config/initializers/secret_token.rb

YourAppName::Application.config.secret_key_base = if Rails.env.development? or Rails.env.test? # generate simple key for test and development environments
  ('a' * 30) # should be at least 30 chars long
else
  ENV['SECRET_TOKEN']
end

本文 (有点旧)很长,但实际上充满了有关该主题的有用信息。


更新04.05.15

从Rails 4.2开始,不再有secret_token.rb文件。按照新的约定,有一个config/secrets.yml文件旨在存储应用程序的机密。

阅读有关如何根据创新将现有应用程序升级到4.2.x的内容。


从技术上讲,其目的secrect_key_base是成为应用程序key_generator方法的秘密输入(检查Rails.application.key_generator)。

该应用程序的key_generator,因此secret_key_base,被Rails框架中的三个核心功能所使用:

  • 可通过访问的加密cookie的派生密钥 cookies.encrypted
  • 派生HMAC签名的cookie的密钥,该密钥可通过访问cookies.signed
  • 导出所有应用程序命名message_verifier实例的密钥。

@michaeljcoyne文章中查看更多关于这三个方面的信息


请注意,如果您使用的是类似Ansible或类似的东西进行部署,则可以在生产部署期间替换整个secret.yml,config/secret.yml如果愿意,可以替换gitignore 。
克里斯(Kris)

实际上,从Rails 4.1
Fumisky Wells

所有这些意味着,当您进行更改时secret_key_base,您的用户将被注销。至少。
x-yuri

24

secret_key_base用于加密和签名会话

为了安全地在cookie中来回发送会话


Rails 4中

  1. 如果您的应用程序名为Hello,并且
  2. 您设置了session['a'] = 'b'

您的Cookie将如下所示:

_Hello_session=BAh7B0kiD3%3D%3D--dc40a55cd52fe32bb3b84ae0608956dfb5824689

转换为:

_Hello_session=<encrypted a=b>--<digital signature>

Cookie由服务器设置并保留在客户端,每次我们请求页面时,浏览器都会将设置的Cookie重新发送到服务器。

为了防止邪恶的人理解a=b字符串,它是加密的
为了防止邪恶的人篡改cookie,使用了数字签名

在这两种情况下,都使用secret_key_base值(用于加密/解密a = b并验证数字签名)。


1.据我所知会话数据保存在服务器中,并且cookie中有一个session_id。例如。将user_id存储在会话中,浏览器只能看到唯一的session_id,而登录后服务器就可以知道哪个用户通过session_id发送请求。在这里,您说session ['a'] ='b'将加密cookie中的数据。我不确定您是否在会话和Cookie之间感到困惑。2.浏览器如何在不知道secret_key_base的情况下解密它并获取信息?
袁咏仪

3
抱歉,现在我知道Rails使用的是基于cookie的会话,这意味着会话信息存储在cookie中。
袁咏仪

是的,这是正确的,基于cookie的会话为分布式应用程序服务器中的会话提供了可移植性,并提高了速度
哈马迪(Hammady)17-10-18
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.