Never hardcode sensitive information (account credentials, passwords, etc.)。相反,创建一个文件将该信息存储为环境变量(键/值对),并将该文件从源代码管理系统中排除。例如,就 Git(源代码管理系统)而言,通过将其添加到 .gitignore 来排除该文件:
-bash> echo '/config/app_environment_variables.rb' >> .gitignore
/config/app_environment_variables.rb
ENV['HTTP_USER'] = 'devuser'
ENV['HTTP_PASS'] = 'devpass'
同样,在/config/environment.rb 的require 行和Application.initialize 行之间添加以下行:
# Load the app's custom environment variables here, so that they are loaded before environments/*.rb
app_environment_variables = File.join(Rails.root, 'config', 'app_environment_variables.rb')
load(app_environment_variables) if File.exists?(app_environment_variables)
就是这样!
正如上面的评论所说,通过这样做,您将在environments/*.rb 之前加载您的环境变量,这意味着您将能够在这些文件中引用您的变量(例如environments/production.rb)。与将环境变量文件放在 /config/initializers/ 中相比,这是一个很大的优势。
在app_environment_variables.rb 内部,没有必要区分开发或生产的环境,因为您永远不会将此文件提交到您的源代码管理系统中,因此它是默认情况下用于 development 上下文。但是,如果您需要为 test 环境(或在您测试 production 模式 locally 的场合)设置一些特殊的东西,只需添加一个条件块下面所有其他变量:
if Rails.env.test?
ENV['HTTP_USER'] = 'testuser'
ENV['HTTP_PASS'] = 'testpass'
end
if Rails.env.production?
ENV['HTTP_USER'] = 'produser'
ENV['HTTP_PASS'] = 'prodpass'
end
每当您更新app_environment_variables.rb 时,请重新启动应用服务器。假设您使用的是 Apache/Passenger 或 rails server 之类的:
-bash> touch tmp/restart.txt
在你的代码中,引用环境变量如下:
def authenticate
authenticate_or_request_with_http_basic do |username, password|
username == ENV['HTTP_USER'] && password == ENV['HTTP_PASS']
end
end
请注意,在app_environment_variables.rb 中,您必须将booleans 和数字 指定为字符串(例如ENV['SEND_MAIL'] = 'false' 而不仅仅是false,以及ENV['TIMEOUT'] = '30' 不仅仅是30),否则你会分别得到can't convert false into String 和can't convert Fixnum into String 的错误。
存储和共享敏感信息
要打结的最后一个结是:如何与您的客户和/或合作伙伴分享这些敏感信息?您的客户和/或合作伙伴恢复网站的全部运营?),您的客户和/或合作伙伴需要知道您的应用所需的所有凭据。通过电子邮件/Skype 发送这些东西是不安全的,并且会导致混乱。将其存储在共享的 Google Docs 中还不错(如果每个人都使用 https),但是专门用于存储和共享密码等小知识的应用程序将是理想的。
如何在 Heroku 上设置环境变量
如果您在 Heroku 上只有一个环境:
-bash> heroku config:add HTTP_USER='herouser'
-bash> heroku config:add HTTP_USER='heropass'
如果您在 Heroku 上有 multiple environments:
-bash> heroku config:add HTTP_USER='staguser' --remote staging
-bash> heroku config:add HTTP_PASS='stagpass' --remote staging
-bash> heroku config:add HTTP_USER='produser' --remote production
-bash> heroku config:add HTTP_PASS='prodpass' --remote production
工头和 .env
Many developers use Foreman(与Heroku Toolbelt 一起安装)到run their apps locally(与使用Apache/Passenger 或rails server 等类似)。 Foreman 和 Heroku 使用Procfile for declaring what commands are run by your application,因此从本地开发人员到 Heroku 的过渡在这方面是无缝的。我在每个 Rails 项目中都使用 Foreman 和 Heroku,所以这种便利性非常好。但事情是这样的.. Foreman loads environment variables stored in /.env via dotenv 但不幸的是dotenv essentially only parses the file for key=value pairs;这些对不会立即成为变量,因此您不能引用已经设置的变量(以保持干燥),也不能在其中执行“Ruby”(如上面的条件语句所述),您可以在/config/app_environment_variables.rb 做。例如,在保持干燥方面,我有时会这样做:
ENV['SUPPORT_EMAIL']='Company Support <support@company.com>'
ENV['MAILER_DEFAULT_FROM'] = ENV['SUPPORT_EMAIL']
ENV['MAILER_DEFAULT_TO'] = ENV['SUPPORT_EMAIL']
因此,我使用 Foreman 在本地运行我的应用程序,但我不使用它的 .env 文件来加载环境变量;相反,我将 Foreman 与上述 /config/app_environment_variables.rb 方法结合使用。