虽然您可以像其他答案一样使用初始化程序,但传统的Rails 4.1+方法是使用config/secrets.yml
。Rails团队引入此问题的原因超出了此答案的范围,但TL; DR的问题在于secret_token.rb
将配置和代码混为一谈,并且存在安全风险,因为令牌已签入到源代码管理历史记录中,并且是唯一需要执行以下操作的系统:知道生产秘密令牌是生产基础结构。
您应该将此文件添加到.gitignore
就像您也不会添加config/database.yml
到源代码管理中一样。
引用Heroku的自己的代码用于设置config/database.yml
从DATABASE_URL
他们的Buildpack为Ruby,我结束了分叉的回购和修改它来创建config/secrets.yml
从SECRETS_KEY_BASE
环境变量。
由于该功能是在Rails 4.1中引入的,因此我认为编辑./lib/language_pack/rails41.rb
和添加此功能是适当的。
以下是我在公司创建的经过修改的buildpack 的摘录:
class LanguagePack::Rails41 < LanguagePack::Rails4
# ...
def compile
instrument "rails41.compile" do
super
allow_git do
create_secrets_yml
end
end
end
# ...
# writes ERB based secrets.yml for Rails 4.1+
def create_secrets_yml
instrument 'ruby.create_secrets_yml' do
log("create_secrets_yml") do
return unless File.directory?("config")
topic("Writing config/secrets.yml to read from SECRET_KEY_BASE")
File.open("config/secrets.yml", "w") do |file|
file.puts <<-SECRETS_YML
<%
raise "No RACK_ENV or RAILS_ENV found" unless ENV["RAILS_ENV"] || ENV["RACK_ENV"]
%>
<%= ENV["RAILS_ENV"] || ENV["RACK_ENV"] %>:
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
SECRETS_YML
end
end
end
end
# ...
end
您当然可以扩展此代码,以添加要从您的环境变量中读取的其他机密信息(例如,第三方API密钥等):
...
<%= ENV["RAILS_ENV"] || ENV["RACK_ENV"] %>:
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
third_party_api_key: <%= ENV["THIRD_PARTY_API"] %>
这样,您可以以非常标准的方式访问此机密:
Rails.application.secrets.third_party_api_key
在重新部署应用程序之前,请确保首先设置环境变量:
然后将修改后的buildpack(或者不欢迎您链接到我的链接)添加到Heroku应用程序中(请参阅Heroku 文档)并重新部署您的应用程序。
config/secrets.yml
每当您git push
访问Heroku 时,作为dyno生成过程的一部分,buildpack都会自动从环境变量中创建您。
编辑:Heroku自己的文档建议创建config/secrets.yml
从环境变量读取,但这意味着您应将此文件检入源代码管理。就我而言,这并不奏效,因为我已经硬编码了我宁愿不签到的开发和测试环境的秘密。