代码之家  ›  专栏  ›  技术社区  ›  stephenmurdoch

在.bashrc环境变量中存储AmazonS3凭据会导致Rails应用程序失败

  •  8
  • stephenmurdoch  · 技术社区  · 14 年前

    我正在开发一个Rails应用程序,它使用回形针在AmazonS3上存储东西。 该应用程序在Heroku上托管。 我正在开发Ubuntu Karmic。

    我将要描述的问题发生在开发(在本地主机上)和生产(在Heroku上)中。


    将s3凭证传递给剪贴纸的标准方法是将它们放入config/s3.yml,如下所示:

    access_key_id: 12345678
    secret_access_key: 903490409fdf09fshsfdoif/43432
    

    当我这样做的时候,一切都很好。但这使得我很难与其他人共享我的代码,所以Heroku建议了一种替代方法- http://docs.heroku.com/config-vars .

    他们建议你把你的s3_密钥和s3_秘密放进你的.bashrc中,就像这样:

    S3_KEY=12345678
    export S3_KEY
    S3_SECRET=903490409fdf09fshsfdoif/43432
    export S3_SECRET
    

    然后,他们建议您创建config/initializers/s3.yml(注意稍微不同的路径),并将以下内容放入该文件中:

    AWS::S3::Base.establish_connection!(
      :access_key_id     => ENV['S3_KEY'],
      :secret_access_key => ENV['S3_SECRET']
    )
    

    但是,当我这样做时,回形针抛出一个摇摆器,并吐出以下错误消息:

    undefined method `stringify_keys' for #<String:0xb6d6c3f4>
    
    /vendor/plugins/paperclip/lib/paperclip/storage.rb:176:in `parse_credentials'
    /vendor/plugins/paperclip/lib/paperclip/storage.rb:138:in `extended'
    /vendor/plugins/paperclip/lib/paperclip/storage.rb:137:in `instance_eval'
    /vendor/plugins/paperclip/lib/paperclip/storage.rb:137:in `extended'
    
    .... other stuff 
    

    很明显,这一切都是在storage.rb模块中启动的。单步执行堆栈跟踪:

    第176行的parse_credentials方法已被标记-以下是代码中显示的调用:

    def parse_credentials creds
      creds = find_credentials(creds).stringify_keys
      (creds[RAILS_ENV] || creds).symbolize_keys
    end
    

    parse_credentials方法尝试调用另一个方法,查找_credentials,这就是我认为问题所在。以下是查找凭据的代码:

    def find_credentials creds
        case creds
        when File
          YAML::load(ERB.new(File.read(creds.path)).result)
        when String
          YAML::load(ERB.new(File.read(creds)).result)
        when Hash
          creds
        else
          raise ArgumentError, "Credentials are not a path, file, or hash."
        end
    end
    

    我看不到find_credentials方法如何能够从.bashrc文件中读取值。它有两种情况可以从yaml中读取,一种情况是寻找散列值。

    我的模型引用的凭据如下:

      has_attached_file :photo,
                    (some code removed)
                    :s3_credentials => "#{RAILS_ROOT}/config/initializers/s3.yml",
    

    如果我从模型中删除:s3_凭证哈希,字符串化_键错误将消失,Rails控制台将抛出出现在find_凭证方法末尾的错误消息:即“凭证不是路径、文件或哈希”。

    所以我被难住了。我意识到这可能是Heroku的一个问题(我将把这个链接通过电子邮件发送给谁,希望他们能回答),也可能是thoughtbot的doods的一个问题。

    正如我在开头所说,当我采用标准方法将我的密钥和秘密插入config/s3.yml时,我的应用程序运行良好,但我更喜欢使用Heroku建议的方法,因为它使我的事情变得更简单,这意味着我可以将我的回购存储在我的公共GitHub页面上,供其他人使用,而无需编写任何客户合并数据。Git中的rivers使我的API密钥不在公共域中。

    我尝试将env变量粘贴到etc/bash.bashrc以及~/.bashrc中,重新启动后,我仍然有相同的问题。这些问题发生在开发机器和Heroku上。我已经确保将配置变量也推到Heroku上。

    3 回复  |  直到 6 年前
        1
  •  13
  •   stephenmurdoch    14 年前

    经过多次搜索,我在这里找到了答案。- http://tammersaleh.com/posts/managing-heroku-environment-variables-for-local-development

    诀窍是完全删除s3.rb文件,只引用模型中的env变量,如下所示:

    has_attached_file :photo, 
                      #...
                      :storage        => :s3, 
                      :bucket         => ENV['S3_BUCKET'],
                      :s3_credentials => { :access_key_id     => ENV['S3_KEY'], 
                                           :secret_access_key => ENV['S3_SECRET'] }
    

    不管怎样,大卫,谢谢你的建议。我不知道你是否想更新Heroku文档来说明一些用户必须这样做。不过,再次感谢。

        2
  •  2
  •   David Dollar    14 年前

    重命名文件 config/initializers/s3.yml config/initializers/s3.rb 试试看。

        3
  •  1
  •   dandan78 Tom Cool    13 年前

    这是你的问题:

    :bucket         => ENV['S3_BUCKET'],
    

    需要

    :bucket         => <%= ENV['S3_BUCKET'] %>,
    

    也就是说,作业没有被解释。