虽然您可以像其他答案一样使用初始化程序,但常规的Rails 4.1+方法是使用
config/secrets.yml
。Rails团队引入这个的原因超出了本答案的范围,但简而言之是因为
secret_token.rb
混淆了配置和代码,并且存在安全风险,因为令牌被检入源代码控制历史记录中,唯一需要知道生产秘密令牌的系统是生产基础架构。
您应该像不将config/database.yml
添加到源代码控制中一样,将此文件添加到.gitignore
中。
参考Heroku自己的代码来设置config/database.yml
从DATABASE_URL
在他们的Buildpack for Ruby中,我最终forking their repo并修改它以从SECRETS_KEY_BASE
环境变量创建config/secrets.yml
。
自从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
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
在重新部署应用程序之前,请确保先设置您的环境变量:
![在Heroku仪表板中设置SECRET_KEY_BASE](https://istack.dev59.com/W5NUv.webp)
然后将修改过的构建包(或者您可以链接到我的构建包)添加到您的Heroku应用程序中(请参阅Heroku的
文档),并重新部署您的应用程序。
构建包将在每次向Heroku进行
git push
时作为动态构建过程的一部分自动从您的环境变量创建
config/secrets.yml
。
编辑:Heroku自己的
文档建议创建
config/secrets.yml
以从环境变量中读取,但这意味着您应该将此文件检入源代码控制。在我的情况下,这不起作用,因为我有硬编码的秘密用于开发和测试环境,我宁愿不要检查它们。
secret.yml
还是secrets.yml
? - James