【问题标题】:How to use secrets.yml for API_KEYS in Rails 4.1?如何在 Rails 4.1 中为 API_KEYS 使用 secrets.yml?
【发布时间】:2014-12-17 08:47:09
【问题描述】:

在我最近的一个项目中,我从.gitignoring 开始使用包含机密和环境变量的文件。因此,除了包含第三方机密的文件(例如 Stripe、Twitter API 或 Facebook Graph 或内部 api_keys,也就是 ./config/initializers/secret_token.rb 文件)之外,整个项目都提交给 repo。

现在我正处于项目即将上线的时刻(兴奋!),我需要使用 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 [对 Denise 的回答,如下]。

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

EDIT3:是的!根据blog,可以通过 secrets.yml 发送 API_keys。有时间会分享我的发现。 :-)

【问题讨论】:

    标签: ruby-on-rails security capistrano


    【解决方案1】:

    第一条规则:不要将secrets.yml 签入到 repo。

    好的,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 on-the-fly。

    旁注:注意 .yml 文件中的空格和制表符。它必须具有正确的格式和间距(例如在 ':' 符号后有一个空格)。

    要在生产环境中设置它,您可以直接从本地 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
    

    就是这样。

    【讨论】:

    • 最后一部分(访问)对我不起作用。我使用过这个解决方案:您可以使用 Rails.application.secrets.key_name 访问
    【解决方案2】:

    Rails.application.secrets.key_name

    【讨论】:

      【解决方案3】:

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

      export API_KEYS=apikeygoeshere
      

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

      那么在production.rb中,你可以将那些环境变量引用为:

      ENV["API_KEYS"]
      

      另一种选择是使用 ruby​​ gem,它基本上可以为您解决这个问题,例如 figaro。它的工作方式是您创建另一个您不签入的文件,figaro 负责将它们设置为环境变量,然后您可以使用 ENV["API_KEYS"] 在您的 development.rb/production.rb 脚本中引用它更多。因为您没有签入包含所有环境变量的文件,所以您必须找到某种方法将该文件放到运行代码的任何机器上。

      【讨论】:

      • 感谢丹妮丝带我去费加罗。会检查出来!是否也可以通过 secrets.yml 携带这些秘密和环境变量?虽然我没有发现任何传单这样做。
      • 在 travis ci 中测试时会发生什么?我需要为项目提供我的 api 才能工作。但是会暴露。我不能在这里玩环境变量。那我该怎么办?
      【解决方案4】:

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

      见:http://edgeguides.rubyonrails.org/5_1_release_notes.html#encrypted-secrets

      【讨论】:

        【解决方案5】:

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

        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
        

        【讨论】:

          猜你喜欢
          • 2014-10-07
          • 2014-03-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多