我的个人 Rails 项目使用了一些 API,我将 API 密钥/秘密存储在 config/environments/production.yml 和 development.yml 作为全局变量。我现在想把这个项目推送到 github 上供其他人使用,但我不希望他们拥有那些敏感数据。我也不希望 .gitignore 中有这个文件,因为它是应用程序运行所必需的。我考虑过将它们放在数据库中的某个地方,但我希望能找到更好的解决方案。
5 回答
TLDR:使用环境变量!
我认为@Bryce 的评论提供了一个答案,我将把它冲洗掉。Heroku 推荐的一种方法似乎是使用环境变量来存储敏感信息(API 密钥字符串、数据库密码)。所以调查你的代码,看看你在哪里有敏感数据。然后创建存储敏感数据值的环境变量(例如在您的 .bashrc 文件中)。例如对于您的数据库:
export MYAPP_DEV_DB_DATABASE=myapp_dev
export MYAPP_DEV_DB_USER=username
export MYAPP_DEV_DB_PW=secret
现在,在您的本地框中,您只需在需要敏感数据时参考环境变量。例如在 database.yml 中:
development:
adapter: mysql2
encoding: utf8
reconnect: false
database: <%= ENV["MYAPP_DEV_DB_DATABASE"] %>
pool: 5
username: <%= ENV["MYAPP_DEV_DB_USER"] %>
password: <%= ENV["MYAPP_DEV_DB_PW"] %>
socket: /var/run/mysqld/mysqld.sock
我认为 database.yml 只是在应用程序的初始化或重新启动时被解析,所以这不应该影响性能。因此,这将为您的本地开发和公开您的存储库解决它。剥离敏感数据后,您现在可以像私下一样使用相同的公共存储库。如果您在 VPS 上,它也可以解决问题。只需 ssh 到它并在您的生产主机上设置环境变量,就像您在开发框中所做的那样。
同时,如果您的生产设置涉及无法 ssh 到生产服务器的手动部署,就像 Heroku 那样,您需要了解如何远程设置环境变量。对于 Heroku,这是通过heroku config:add
. 因此,根据同一篇文章,如果您将 S3 集成到您的应用程序中,并且您的敏感数据来自环境变量:
AWS::S3::Base.establish_connection!(
:access_key_id => ENV['S3_KEY'],
:secret_access_key => ENV['S3_SECRET']
)
只需让 Heroku 为其创建环境变量:
heroku config:add S3_KEY=8N022N81 S3_SECRET=9s83159d3+583493190
这个解决方案的另一个优点是它是语言中立的,而不仅仅是 Rails。适用于任何应用程序,因为它们都可以获取环境变量。
这个怎么样...
创建一个新项目并将其签入 GitHub,并在 production.yml 和 development.yml 文件中使用占位符值。
更新 .gitignore 以包含 production.yml 和 development.yml。
用您的秘密替换占位符值。
现在,您可以将代码签入 GitHub,而不会泄露您的秘密。
并且任何人都可以克隆您的存储库,而无需任何额外的步骤来创建丢失的文件(他们只会像您一样替换占位符值)。
这符合你的目标吗?
它们可能最好放在初始化程序(config/initializers/api.yaml)中,尽管我认为你做的很好。将实际密钥添加到您的 .gitignore 文件并运行git rm config/environments/production.yml
以从您的存储库中删除该敏感数据。公平警告,它也会删除该文件,因此请先备份它。
然后,只需在您的实际文件旁边创建一个 config/environments/production.yml.example 文件,其中包含相关详细信息,但不包含敏感数据。当您将其投入生产时,只需复制不带 .example 的文件并替换适当的数据。
使用环境变量。
在 Ruby 中,它们可以像这样访问:
ENV['S3_SECRET']
两个原因:
- 这些值不会进入源代码管理。
- 无论如何,“敏感数据”又名密码往往会在每个环境的基础上发生变化。例如,您应该使用不同的 S3 凭据进行开发与生产。
这是最佳做法吗?
是:http: //12factor.net/config
我如何在本地使用它们?
foreman和dotenv都很简单。或者,编辑您的shell。
我如何在生产中使用它们?
在很大程度上,这取决于。但是对于 Rails,dotenv是一个轻松的胜利。
平台即服务呢?
任何 PaaS 都应该为您提供设置它们的方法。例如 Heroku:https ://devcenter.heroku.com/articles/config-vars
这不会使为项目设置新开发人员变得更加复杂吗?
也许吧,但这是值得的。您始终可以将 .env.sample 文件签入源代码管理,其中包含一些示例数据。将有关它的注释添加到项目的自述文件中。
Rails 4.1 现在有一个约定。您将这些内容存储在 secrets.yml 中。因此,您最终不会在您的应用程序中分散一些全局 ENV 调用。
这个 yaml 文件就像解析后的 database.yml erb,所以你仍然可以在这里使用 ENV 调用。在这种情况下,您可以将其置于版本控制之下,然后它将仅用作必须使用 ENV vars 的文档。但是您也可以将其从版本控制中排除,并将实际的秘密存储在那里。在这种情况下,您会将一些 secrets.yml.default 或类似内容放入公共 repo 以用于文档目的。
development:
s3_secret: 'foo'
production:
s3_secret: <%= ENV['S3_SECRET']%>
比你可以在下面访问这些东西
Rails.application.secrets.s3_secret
在本集的开头详细讨论了它