如何在Rails 4.1中使用secrets.yml for API_KEYS?

时间:2014-10-21 23:58:44

标签: ruby-on-rails security capistrano

在我最近的一个项目中,我从.gitignoring开始了包含秘密和环境变量的文件。所以整个项目都致力于repo,除了包含第三方秘密的文件,如Stripe,Twitter API或Facebook Graph或内部api_keys,ala ./config/initializers/secret_token.rb文件。

现在我正处于项目即将上线的地步(兴奋!)我需要使用Capistrano将所有环境变量移植到生产服务器上,即cap production deploy.

[编辑4:你,2018年] 在initializers / secret_token.rb的情况下,很明显Rails 4.1有一种处理secrets.yml file的新方法,它将:secret_key_base值提取到生产服务器。在这里,我建议使用开箱即用的capistrano-secrets-yml gem,并且使用起来很简单。

剩下的是将其他秘密(如API_KEYS,APP_ID等)带到生产服务器而不检查任何进入仓库的方法。如何做到这一点,最推荐/最安全的方式或最佳做法是什么?

注意:我会随着问题的进展编辑问题/我会更清晰。

EDIT1:服务器是DigitalOcean上的Ubuntu / Linux VPS [回答丹尼斯,下面]。

EDIT2:env_variables / secrets可以通过secrets.yml转发到服务器吗?会话的Secret_token毕竟不是唯一的秘密! [在Edit3上回答]

EDIT3:是的!可以根据此blog通过secrets.yml发送API_keys。将在某个时候分享我的发现。 : - )

5 个答案:

答案 0 :(得分:42)

第一条规则:不要检查secrets.yml进入回购。

好的,这里是secret.yml的样子:

development:
  secret_key_base: 6a1ada9d8e377c8fad5e530d6e0a1daa3d17e43ee... 
  # Paste output of $ rake secret here for your dev machine.

test:
  secret_key_base: _your_secret_ as above

production:
  secret_key_base: <%= secure_token %>


  STRIPE_PUBLISHABLE_KEY: 'Put your stripe keys for production'
  STRIPE_SECRET_KEY: 'Put actual keys for production here'
  FB_APP_SECRET: 'same as above'
  FB_CALLBACK_URL: 'FB url here'
  FB_CALLBACK_UPDATE_URL: 'FB url here'
  GOOGLE_KEY: 'Put your keys for production'
  GOOGLE_SECRET: 'same as above'
  TWITTER_KEY: 'same as above'
  TWITTER_SECRET: 'same as above'
  TWITTER_USERNAME: 'same as above'
  LINKEDIN_KEY: 'same as above'
  LINKEDIN_SECRET: 'same as above'

请注意secure_token块中的production:。在生产服务器上,我即时使用初始化程序dynamically generate secret_tokens

  

旁注:注意.yml文件中的空格和制表符。它必须正确格式化并间隔开(例如在&#39;:&#39;符号后面有空格。)

要在制作时设置它,您可以直接从本地scp文件或使用capistrano-secrets-yml gem。

  

这不起作用。根据@ OddityOverseer的答案,查看更新后的方法。

要访问应用environments/production.rb中的环境变量,请使用:

FB_APP_SECRET            = ENV['FB_APP_SECRET']
FB_CALLBACK_URL          = ENV['FB_CALLBACK_URL']
FB_CALLBACK_UPDATE_URL   = ENV['FB_CALLBACK_UPDATE_URL']
GOOGLE_KEY               = ENV['GOOGLE_KEY']
GOOGLE_SECRET            = ENV['GOOGLE_SECRET']
TWITTER_KEY              = ENV['TWITTER_KEY']
TWITTER_SECRET           = ENV['TWITTER_SECRET']
TWITTER_USERNAME         = ENV['TWITTER_USERNAME']
LINKEDIN_KEY             = ENV['LINKEDIN_KEY']
LINKEDIN_SECRET          = ENV['LINKEDIN_SECRET']

  

2016年8月更新:

要访问应用environments/production.rb中的环境变量,请使用:

FB_APP_SECRET            = Rails.application.secrets.FB_APP_SECRET
FB_CALLBACK_URL          = Rails.application.secrets.FB_CALLBACK_URL
FB_CALLBACK_UPDATE_URL   = Rails.application.secrets.FB_CALLBACK_UPDATE_URL
GOOGLE_KEY               = Rails.application.secrets.GOOGLE_KEY
GOOGLE_SECRET            = Rails.application.secrets.GOOGLE_SECRET
TWITTER_KEY              = Rails.application.secrets.TWITTER_KEY
TWITTER_SECRET           = Rails.application.secrets.TWITTER_SECRET
TWITTER_USERNAME         = Rails.application.secrets.TWITTER_USERNAME
LINKEDIN_KEY             = Rails.application.secrets.LINKEDIN_KEY
LINKEDIN_SECRET          = Rails.application.secrets.LINKEDIN_SECRET

关于它。

答案 1 :(得分:28)

Rails.application.secrets.key_name

答案 2 :(得分:8)

一种方法是将这些密钥存储在环境变量中。如何设置环境变量因您使用的操作系统而异。对于Linux机器,通常您在主目录中编辑.bashrc或.bash_profile文件并添加如下所示的行:

export API_KEYS=apikeygoeshere

您必须为任何将运行rails的用户编辑该文件。

然后在production.rb中,您可以将这些环境变量称为:

ENV["API_KEYS"]

另一个选择是使用红宝石宝石,基本上为你照顾,如figaro。它的工作方式是你创建另一个你无法检入的文件,figaro负责将它们设置为环境变量,然后你可以使用{在development.rb / production.rb脚本中引用它们。 {1}}以上。因为您没有检查包含所有环境变量的文件,所以您必须找到一些方法将该文件放到运行代码的任何机器上。

答案 3 :(得分:3)

我知道这个问题特定于Rails 4.1,但升级到Rails 5.1的人现在包含内置的秘密生成。这似乎是一种更好的方法来处理rails应用程序中的敏感数据。

请参阅:http://edgeguides.rubyonrails.org/5_1_release_notes.html#encrypted-secrets

答案 4 :(得分:0)

处理不同环境的一个好方法是:

EDITOR=vim rails credentials:edit
development:
  cloudinary:
    cloud_name: dxe1hjkoi
    api_key: 361019726125669
    api_secret: Cn6tHfSf019278367sZoO083eOI
production:
  cloudinary:
    cloud_name: oiajsu98u
    api_key: 091828812791872
    api_secret: KJS98182kjaksh89721jhS9812j

然后将其用作:

Cloudinary.config do |config|
  config.cloud_name = 
    Rails.application.credentials.dig(Rails.env.to_sym, :cloudinary, :cloud_name)
  config.api_key = 
    Rails.application.credentials.dig(Rails.env.to_sym, :cloudinary, :api_key)
  config.api_secret = 
    Rails.application.credentials.dig(Rails.env.to_sym, :cloudinary, :api_secret)
end