【问题标题】:How to upload a json file with secret keys to Heroku如何将带有密钥的 json 文件上传到 Heroku
【发布时间】:2016-05-10 16:58:16
【问题描述】:

我正在构建一个 rails 应用程序,它使用适用于 Ruby 的 Google Api 客户端库从 Google Analytics 中提取数据。

我正在使用 OAuth2,并且可以在本地计算机上进行开发中的所有工作。我的问题是该库使用下载的文件client_secrets.json 来存储两个密钥。

问题:我正在使用 Heroku,需要一种方法将文件获取到他们的生产服务器。

我不想将此文件添加到我的 github 存储库中,因为该项目是公开的。

如果有办法将文件临时添加到 git,推送到 Heroku,然后从 git 中删除,那很好。我的感觉是密钥将在提交中,并且很难防止在 github 上显示。

试过了: 据我所知,您不能通过 Bash 控制台将文件 SCP 发送到 Heroku。我相信这样做时你会得到一个新的 Dyno,你添加的任何东西都只是暂时的。我试过了,但无法让 SCP 正常工作,所以不能 100% 确定这一点。

试过了: 我查看了将 JSON 文件存储在 Environment 或 Config Var 中,但无法使其正常工作。如果有人有想法,这似乎是最好的方法。当 ruby​​ 将 JSON 转换为字符串或散列时,我经常遇到麻烦,所以我可能只需要这里的指导。

试过了: 此外,我试图找出一种方法来从 JSON 文件中提取密钥,将它们放入 Config Vars,然后将 JSON 文件添加到 git。不过,我想不出将ENV["KEY"] 放入JSON 文件的方法。


示例代码 Google library has a method 加载 JSON 文件以创建授权客户端。然后客户端获取令牌(或提供授权 url)。

client_secrets = Google::APIClient::ClientSecrets.load('client_secrets.json')
auth_client = client_secrets.to_authorization

** 请注意,谷歌页面上的示例没有显示文件名,因为它使用了设置为路径的默认 ENV Var

我认为如果ClientSecrets.load() 方法只采用JSON、字符串或哈希值,这一切都会容易得多,这些可以进入配置变量。

不幸的是,它似乎总是需要一个文件路径。当我给它提供 JSON、字符串或哈希时,它会爆炸。 I've seen someone get around the issue with a p12 key here,但我不确定如何在我的情况下复制它。

没试过: 我唯一的其他方法(除了迁移到 AWS 之外)是将 JSON 文件放在 AWS 上,并在需要时让 rails 将其拉出。我不确定这是否可以即时完成,或者在 rails 服务器启动时是否需要拉下文件。看起来工作量太大了,但在这一点上,我已经花了几个小时准备尝试。

这是我正在处理的特定控制器: https://github.com/dladowitz/slapafy/blob/master/app/controllers/welcome_controller.rb

【问题讨论】:

    标签: ruby-on-rails ruby json git heroku


    【解决方案1】:

    我在使用 Google API 时遇到了同样的问题。我最终使用 openssl 为 p12 文件分配了一个新的非常机密的密码,将该新文件存储在 repo 中,然后将密码放入应用程序机密和 Heroku 环境变量中。

    这样,文件在 repo 中,但没有密码就无法访问/读取。

    This 帖子有助于将默认的 google p12 密码从“notasecret”更改为安全密码。

    def authorize!
      @client.authorization = Signet::OAuth2::Client.new(
        #...
        :signing_key => key
      )
    end
    
    def key
      Google::APIClient::KeyUtils.load_from_pkcs12(key_path, ENV.fetch('P12_PASSPHRASE'))
    end
    
    def key_path
      "#{Rails.root}/config/google_key.p12"
    end
    

    【讨论】:

      【解决方案2】:

      通过搜索 github,我发现有人使用了另一种方法,使用 JSON 字符串作为参数而不是文件路径:Google::APIClient::ClientSecrets.new(JSON.parse(ENV['GOOGLE_CLIENT_SECRETS']))

      这让我可以将 JSON 包装成一个 ENV VAR。世界再次变得有意义。

      【讨论】:

      • 您如何将 json 数据存储在 env var 中(即换行符、引号)?我可以在控制台中使用此行导入它,但我尝试完全按照您在控制器中的设置进行设置,并且在调用此行时,我在 ClientSecrets 的初始化函数中得到“没有将符号隐式转换为整数” .我尝试访问它失败的项目没有问题,所以它一定是在两者之间的某个地方丢失了。
      • 我正在使用 figaro gem,然后将我的环境变量存储在 application.yml 中。在这个文件中,我像这样设置了变量:GOOGLE_CLIENT_SECRETS: '{"web":{"client_id":"XXXXXX-XXXXXXXXXXXX.apps.googleusercontent.com","project_id":"XXXX-XXXX","auth_uri":"https://accounts.google.com/o/oauth2/auth","token_uri":"https://accounts.google.com/o/oauth2/token","auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs","client_secret":"XXXXXXXXXX","redirect_uris":["http://localhost:3000/oauthredirect"]}}'
      • @paullj1 在 Heroku 中,Config Var 值几乎相同,但我删除了最外层的单引号。在上面的解决方案中需要注意的一件事是,我发现了一种不采用文件名的不同方法。原来我用的是Google::APIClient::ClientSecrets.load() 现在我用的是Google::APIClient::ClientSecrets.new()
      【解决方案3】:

      正如this thread 中所讨论的,您可以设置三个 ENV 变量,而不是提供 json 密钥文件的路径:

      GOOGLE_ACCOUNT_TYPE=service_account
      GOOGLE_PRIVATE_KEY=XXX
      GOOGLE_CLIENT_EMAIL=XXX
      

      Source here.

      【讨论】:

      • 这似乎可以使用 Cloud Natural Language API 并为我省去了很多麻烦。
      • 嗨@Nick - 很抱歉挖掘旧工作 - 我处于同样的困境中,想知道你是如何为自然语言 API 解决这个问题的?
      • @gezquinndesign 这是一个非生产应用程序,但最后我只是在 development.rb 中设置了 ENV['GOOGLE_PRIVATE_KEY'] 等,它就可以工作了......
      猜你喜欢
      • 1970-01-01
      • 2016-11-22
      • 2017-05-05
      • 2019-05-06
      • 2021-02-01
      • 2017-09-29
      • 2014-07-10
      • 2016-06-14
      • 2021-02-08
      相关资源
      最近更新 更多