将rails表单的策略和签名问题发布到s3上载

时间:2012-12-26 21:24:11

标签: ruby-on-rails post upload amazon-s3

我正在尝试关注this "how-to"(从POST到S3存储桶)并且似乎在我的策略和签名上失败了。

我不太确定我的政策和签名是错的?但我知道我在评估我在助手中创建的方法时遇到了问题。我试过转换政策&amp;符号<%= :S3_UPLOAD_SIGNATURE %>的签名值,我尝试过&lt;%= h,&lt;%= raw,“#{&lt;%= ..}”。

之前我已经调用了辅助方法,没有任何问题,所以我有点迷失。

错误:

NameError in Proj_files#new

Showing /app/views/proj_files/new.html.erb where line #8 raised:

uninitialized constant ActionView::CompiledTemplates::S3_UPLOAD_POLICY
Extracted source (around line #8):

5:       <input type="hidden" name="AWSAccessKeyId" value= <%= ENV['AWS_ACCESS_KEY_ID'] %> > 
6:       <input type="hidden" name="acl" value="private"> 
7:       <input type="hidden" name="success_action_redirect" value="http://localhost/">
8:       <input type="hidden" name="policy" value= <%= S3_UPLOAD_POLICY %> >
9:       <input type="hidden" name="signature" value= <%= S3_UPLOAD_SIGNATURE %> >
10:       <input type="hidden" name="Content-Type" value="image/png">
11:       <!-- Include any additional input fields here -->

我有一个带有相应new.html.erb的proj_files控制器:

<form action="https://s3.amazonaws.com/MY_BUCKET" method="post" enctype="multipart/form-data">
  <input type="hidden" name="key" value="uploads/${filename}">
  <input type="hidden" name="AWSAccessKeyId" value= <%= ENV['AWS_ACCESS_KEY_ID'] %> > 
  <input type="hidden" name="acl" value="private"> 
  <input type="hidden" name="success_action_redirect" value="http://localhost/">
  <input type="hidden" name="policy" value= <%= S3_UPLOAD_POLICY %> >
  <input type="hidden" name="signature" value= <%= S3_UPLOAD_SIGNATURE %> >
  <input type="hidden" name="Content-Type" value="image/png">
  <!-- Include any additional input fields here -->

  File to upload to S3: 
  <input name="file" type="file"> 
  <br> 
  <input type="submit" value="Upload File to S3"> 
</form> 

和proj_files_helper.rb:

module ProjFilesHelper

  def S3_UPLOAD_POLICY options = {}
    options[:content_type] ||= ''
    options[:acl] ||= 'private'
    options[:max_file_size] ||= 500.megabyte
    options[:path] ||= ''

    Base64.encode64(
      "{'expiration': '#{10.hours.from_now.utc.strftime('%Y-%m-%dT%H:%M:%S.000Z')}',
        'conditions': [
          {'bucket': '#{ENV['S3_BUCKET']}'},
          ['starts-with', '$key', ''],
          {'acl': '#{options[:acl]}'},
          {'success_action_status': '201'},
          ['content-length-range', 0, #{options[:max_file_size]}],
          ['starts-with','$Content-Type','']
        ]
    }").gsub(/\n|\r/, '')
  end


  def S3_UPLOAD_SIGNATURE options = {}
    Base64.encode64(
      OpenSSL::HMAC.digest(
      OpenSSL::Digest::Digest.new('sha1'),
      ENV['AWS_SECRET_ACCESS_KEY'], s3_policy(options))).gsub("\n","")
  end

end

谢谢你看看!

更新 我将方法名称更改为小写,这让我更进一步(我应该意识到这一点!)。

现在我收到一个S3错误:

<Error>
<Code>AccessDenied</Code>
<Message>
Invalid according to Policy: Policy Condition failed: ["eq", "$bucket", "MY_BUCKETS_NAME"]
</Message>

似乎可能有一个ENV变量$ bucket坏参考我会寻找...“MY_BUCKETS_NAME”确实显示了正确的桶名称....如果有人可以提供任何帮助,以获得rails post form to S3 up并且运行/指出我的错误我很感激。

由于

UPDATE2 我在下面的评论中将表单操作修改为“https://s3.amazonaws.com/MY_BUCKET”并收到此错误:

Invalid according to Policy: Policy Condition failed: ["eq", "$acl", "public-read"]

越来越近了......谢谢!

UPDATE3 我正在打架!

我已将策略和表单ACL修改为具有相同的一致值(私有或公共读取)。

下面的评论让我将表单操作修改为:http://MY_BUCKET.s3.amazonaws.com/我收到此错误:

<Code>AccessDenied</Code>
<Message>
Invalid according to Policy: Policy Condition failed: ["eq", "$success_action_status", "201"]
</Message>

奇怪的是,当我转到AWS S3管理控制台并将文件上传到我的存储桶时,它告诉我链接是“http://s3.amazonaws.com/MY_BUCKET”形式。我在amazonaws之前和之后添加了MY_BUCKET,但仍然收到同样的错误...

我不确定发生错误配置的地方......我打算创建一个新的存储桶,看看我是否设置错误....

谢谢!

现在可以工作!!! 我从答案中解决了所有问题...但后来不得不再做一次改变......

我的表单有一个“success_action_redirect”字段,但我的政策有一个success_action_status!

政策和表单字段必须匹配! DUH!

感谢所有帮助...时间进一步调整它!

2 个答案:

答案 0 :(得分:6)

1 /要上传文件,您必须使用此网址"http://#{bucket_name}.s3.amazonaws.com/"。它已在documentation中明确说明:

  

该操作定义将处理请求的URL;必须将其设置为存储桶的URL。例如,如果您的广告素材的名称是&#34; johnsmith&#34;,那么该网址将是&#34; http://johnsmith.s3.amazonaws.com/&#34;

2 /您必须拥有一致的政策,似乎您在签名中设置public-read并在表单中设置private

答案 1 :(得分:1)

我收到以下错误: 根据策略无效:策略条件失败:[\“eq \”,\“$ bucket \”

经过几个小时,我才知道你不能有一个大写字母的桶。将桶改为小写固定它。