【问题标题】:How to dynamically generate secret tokens in Rails 4.1 with secrets.yml?如何使用 secrets.yml 在 Rails 4.1 中动态生成秘密令牌?
【发布时间】:2014-03-07 14:11:21
【问题描述】:

Rails 新手。按照 Hartl 的教程,他使用此代码为 config/initializers/secret_token.rb 动态生成秘密令牌

require 'securerandom'

def secure_token
  token_file = Rails.root.join('.secret')
  if File.exist?(token_file)
    # Use the existing token.
    File.read(token_file).chomp
  else
    # Generate a new token and store it in token_file.
    token = SecureRandom.hex(64)
    File.write(token_file, token)
    token
  end
end

SampleApp::Application.config.secret_key_base = secure_token

我正在尝试使用 secrets.yml 遵循新的 Rails 4.1 方式,并删除 secret_token.rb:

development:
  secret_key_base: 79c1389c2fadc5a5a1918a5104ab34eb700c

test:
  secret_key_base: fdb4edcde14173d62963705ca4d7876b5307790924

production:
  secret_key_base: 85172605030a8225c083d886d066da2cb4aac1f0

但我认为您不能像在 yml 文件中的 secret_token.rb 中那样运行 ruby​​ 脚本。您将如何让 Rails 动态生成秘密令牌。这应该怎么做?最佳做法是什么?

【问题讨论】:

    标签: ruby-on-rails security ruby-on-rails-4


    【解决方案1】:

    给定一个函数 secret_token,它的唯一工作是在每次应用程序访问 secrets.yml 文件时生成一个新的令牌字符串,cookie 和很可能其他类似会话的行为将无法正常工作,因为秘密令牌每次调用都会更改函数。

    首选且安全的方法是使用 secrets.yml 文件中的任何旧密钥用于开发和测试环境(您可以通过在命令行上发出 rake secret 来生成密钥字符串),然后使用一个环境变量您的生产服务器知道,因此 secrets.yml 文件如下所示:

    production:
     secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
    

    例如,在 Heroku 上,使用 heroku config:set SECRET_KEY_BASE="insert key here" 设置环境变量,然后就可以了。不要害怕将 secrets.yml 文件检入 scm...只要您没有将生产密钥保存到文件中(而是使用我刚刚描述的环境变量方法),将文件检入 scm不构成威胁。

    【讨论】:

    • secrets.yml 文件,顾名思义,是一个secret,因此不应提交到任何存储库。该文件还应该在 Unix 服务器上具有最小的读取权限,因此只有具有足够权限的人才能最初播种它,然后它应该保持不变,并且只能由 rails 应用程序使用。我也曾经从环境中读取变量,但我认为这实际上是一种不好的做法。最后它只是延迟了问题:你必须保护环境和/或使用类似dotenv的东西,它基本上与secrets.yml做同样的事情
    【解决方案2】:

    您实际上可以在 YML 文件中运行 ERB 代码。比如:

    development:
      secret_key_base: <%= secret_token %>
    

    应该可以工作(如果读取 YML 文件的任何进程都可以访问 secure_token 方法)。

    【讨论】:

    • 谢谢。但它会起作用吗? 会在secret_token.rb 中找到secret_token 函数吗? “升级到 Rails 4.1 指南”说你应该删除 secret_token.rb。如果是这样,也许您可​​以将函数放在一个名为 /config/secret_function.rb 的文件中?
    • 我会把它放在 lib 文件夹中。这件事可能有点棘手,因为这个文件很可能在 Rails 启动时被评估,所以即使以后 Rails 模型或控制器可以访问它,此时它仍然可能失败。您可以使用相同的 (不带 = then)直接在 YML 中包含任何其他文件,这可能是这种情况下的最佳方式。
    • 谢谢。你介意回答这个问题吗?它不同,但高度相关:stackoverflow.com/questions/21674774/…
    猜你喜欢
    • 2014-12-17
    • 2013-01-23
    • 2014-10-07
    • 2015-02-21
    • 2023-04-07
    • 2013-06-13
    • 2019-03-10
    • 1970-01-01
    • 2020-08-25
    相关资源
    最近更新 更多