简体   繁体   English

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

[英]How to use secrets.yml for API_KEYS in Rails 4.1?

In one of my recent projects I started out by .gitignoring the files containing secrets and environment variables.在我最近的一个项目中,我从.gitignoring包含机密和环境变量的文件开始。 So the entire project is committed to the repo except the files that contain third party secrets such as that of Stripe, Twitter API or Facebook Graph or internal api_keys, ala the ./config/initializers/secret_token.rb file.因此,除了包含第三方机密的文件(如 Stripe、Twitter API 或 Facebook Graph 的机密或内部 api_keys 的机密文件以及./config/initializers/secret_token.rb文件)之外,整个项目都提交给了 repo。

Now I am at a point where the project is about to go live (excited!) and I need to port all the environment variables on to the production server using Capistrano ie cap production deploy.现在我正处于项目即将上线的时刻(兴奋!),我需要使用 Capistrano 将所有环境变量移植到生产服务器,即cap production deploy.

[Edit 4: Yr, 2018] In case of initializers/secret_token.rb it is clear that Rails 4.1 has a new way of handling secrets.yml file that pulls in the :secret_key_base value to the production server. [Edit 4: Yr, 2018] 在 initializers/secret_token.rb 的情况下,很明显 Rails 4.1 有一种处理secrets.yml 文件的新方法,将 :secret_key_base 值拉入生产服务器。 Here, I recommend using the capistrano-secrets-yml gem which works right out of the box and is dead simple to use.在这里,我建议使用capistrano-secrets-yml gem,它开箱即用,使用起来非常简单。

What is left is the way to carry other secrets like API_KEYS, APP_IDs etc. to the production server without checking any of those into the repo.剩下的是将其他秘密(如 API_KEYS、APP_ID 等)传送到生产服务器而不将其中任何一个检查到存储库中的方法。 How to do this, what is the most recommended/securest way or the best practices?如何做到这一点,最推荐/最安全的方式或最佳实践是什么?

NOTE: I'll be editing the question as it progresses/I get more clarity.注意:我将随着问题的进展进行编辑/我变得更加清晰。

EDIT1: Server is a Ubuntu/Linux VPS on DigitalOcean [Answer to Denise, below]. EDIT1:服务器是 DigitalOcean 上的 Ubuntu/Linux VPS [对 Denise 的回答,如下]。

EDIT2: Can the env_variables/secrets be carried over to the server via secrets.yml? EDIT2:可以通过secrets.yml 将env_variables/secrets 传送到服务器吗? Secret_token for sessions is not the only secret after all!毕竟,会话的 Secret_token 并不是唯一的秘密! [Answered on Edit3] [在Edit3上回答]

EDIT3: Yes! EDIT3:是的! It's possible to send in the API_keys via secrets.yml according to this blog .根据此博客,可以通过 secrets.yml 发送 API_keys 。 Will share my findings in sometime.有时间会分享我的发现。 :-) :-)

First rule: DO NOT CHECK-IN secrets.yml into the repo.第一条规则:不要将secrets.yml入 repo。

All right, here's how a secret.yml would look:好的,这里是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'

Note the secure_token up there in the production: block.注意生产中的secure_token production:块。 On production server I'm using an initializer to dynamically generate secret_tokens on-the-fly.在生产服务器上,我使用初始化程序来动态生成 secret_tokens

sidenote: be careful about spaces and tabs inside the .yml file.旁注:注意 .yml 文件中的空格和制表符。 It must be properly formatted and spaced (such as having a space after the ':' symbol).它必须正确格式化和间隔(例如在“:”符号后有一个空格)。

To set it up on production you could then scp the file directly from your local or use the capistrano-secrets-yml gem.要在生产环境中进行设置,您可以直接从本地 scp 文件或使用capistrano-secrets-yml gem。

This will not work.这是行不通的。 See an updated method as per @OddityOverseer's answer below.根据下面@OddityOverseer 的回答查看更新的方法。

To access the environment variables in your app environments/production.rb use:要访问你的应用程序的环境变量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']

UPDATED August-2016: 2016 年 8 月更新:

To access the environment variables in your app environments/production.rb use:要访问你的应用程序的环境变量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

That's about it.就是这样。

Rails.application.secrets.key_name

One way to do it is to store those secret keys in environment variables.一种方法是将这些密钥存储在环境变量中。 How to set an environment variable is different depending on what operating system you're on.设置环境变量的方式因您使用的操作系统而异。 For a linux machine, usually you're editing a .bashrc or .bash_profile file in your home directory and adding a line that looks like:对于 linux 机器,通常您在主目录中编辑 .bashrc 或 .bash_profile 文件并添加如下所示的行:

export API_KEYS=apikeygoeshere

You'll have to edit the file for whatever user will run rails.您必须为将运行 rails 的任何用户编辑该文件。

Then in production.rb , you can refer to those environment variables as:然后在production.rb ,您可以将这些环境变量引用为:

ENV["API_KEYS"]

Another option is to use a ruby gem that essentially takes care of that for you, like figaro.另一种选择是使用 ruby​​ gem,它基本上可以为您处理这些问题,例如 figaro。 The way it works is that you create another file that you don't check in and figaro takes care of setting them up as environment variables, which you can then refer to in your development.rb/production.rb scripts using the ENV["API_KEYS"] above.它的工作方式是你创建另一个你不签入的文件,figaro 负责将它们设置为环境变量,然后你可以在你的 development.rb/production.rb 脚本中使用ENV["API_KEYS"]以上。 Because you aren't checking in the file that has all of the environment variables, you'll have to find some way to get that file onto whatever machines are running the code.因为您没有检入包含所有环境变量的文件,所以您必须找到某种方法将该文件放到运行代码的任何机器上。

I know this question is specific to Rails 4.1, but those who upgrade to Rails 5.1 it now includes built in secret generation.我知道这个问题特定于 Rails 4.1,但是升级到 Rails 5.1 的人现在包含内置的秘密生成。 Which seems a much better way to handle sensitive data in your rails app.这似乎是在 Rails 应用程序中处理敏感数据的更好方法。

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

A nice approach to deal with different environments would be to:处理不同环境的一个好方法是:

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

Then use it as:然后将其用作:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM