【问题标题】:Intermittent Carrierwave S3 403 Signature Does Not Match errors间歇性 Carrierwave S3 403 签名与错误不匹配
【发布时间】:2012-11-20 12:45:22
【问题描述】:

从我在 heroku 上的应用程序将文件上传到 s3 时,我遇到了看似随机的错误。我正在使用 jquery-file-upload 使用 CORS 方法和此代码将图片上传到我的存储桶中的 tmp/ 目录。

  def url
    temp_url = AWS::S3::S3Object.url_for(
      s3_key,
      S3_CONFIG['bucket'],
      use_ssl: true)
    puts temp_url
    temp_url
    # temp_url.to_s.encode_signs
  end

  def delete_photo_from_s3
    begin
      photo = AWS::S3::S3Object.find(s3_key, S3_CONFIG['bucket'])
      photo.delete
    rescue Exception => e
      Rails.logger.error e.message
    end
  end

  private

  def s3_key
    parent_url = self[:uri]
    # If the url is nil, there's no need to look in the bucket for it
    return nil if parent_url.nil?
    # This will give you the last part of the URL, the 'key' params you need
    # but it's URL encoded, so you'll need to decode it
    object_key = parent_url.split(/\//)
    "#{object_key[3]}/#{object_key[4]}/#{object_key[5]}"
  end

从那里我使用carrierwave 上传和处理这些图像。但是,有时上传会静默失败,并且我的 s3 存储桶中出现 403 Forbidden 错误。不知道是什么原因造成的。

从那里,我使用 Qu 处理后台作业,以使用 remote__url 调用将图像附加到载波。这是我的后台任务:

class PhotoUploader
  def self.perform(finding_id, photo_id)
    begin
      finding = Finding.find(finding_id)
      photo = Photo.find(photo_id)
      upload = finding.uploads.build
      # attached_picture = photo.temp_image_url || photo.url
      upload.remote_attachment_url = photo.url
      if upload.save!
        Rails.logger.debug "#{Time.now}: Photo #{photo_id} saved to finding..."
        photo.set(:delete_at => 1.hour.from_now)  # UTC, same as GMT (Not local time!)
        photos = Photo.where(:processing => true, :delete_at.lte => Time.now.utc)  # Query for UTC time, same type as previous line (also not local time!)
        finding.unset(:temp_image)
        if photos
          photos.each do |photo|
            photo.destroy
            Rails.logger.debug "Photo #{photo.id} - #{photo.uri} destroyed."
          end
        end
      else
        raise "Could not save to s3!"
      end
    rescue Exception => e
      Rails.logger.debug "#{Time.now}: PH01 - Error processing photo #{photo_id}, trying again... :: #{e.message}"
      retry
    end
  end
end

这有时有效,但并非总是如此,这真的很奇怪。 我最终在我的 s3 日志中得到了一堆这些错误:

fc96aee492e463ff67c0a9835c23c81a09c4c36a53cdf297094ded3a7d02c62f actionlog开发[02 / DEC / 2012:20:27:18 0000] 71.205.197.214 - 625CEFB5DB7867A7 REST.GET.OBJECT TMP / 4f75d2fb4e484f2ffd000001 / apcm_photomix1_0022.jpg“GET / actionlog开发/ TMP / 4f75d2fb4e484f2ffd000001 / apcm_photomix1_0022.jpg?AWSAccessKeyId=AKIAI___ZA6A&Expires=1354480332&Signature=4wPc+nT84WEdOuxS6+Ry4iMNkys= HTTP/1.1" 403 SignatureDoesNotMatch 895 - 8 - "-" "Ruby" -

我已经阅读了很多关于此的内容,似乎人们有时会在签名中有未转义的“+”时遇到此问题。我不确定这是 Carrierwave、Fog 还是 AWS::S3 问题。

如果您能提供任何帮助,我们将不胜感激。

谢谢。

【问题讨论】:

  • 遇到了同样的问题。你找到解决办法了吗?
  • 我找到了解决方法。首先,确保您的服务器的系统时间是准确的。这可能会导致来自 AWS 的“时间太偏”错误。然后将此添加到您的carrierwave 上传器def process_uri(uri) URI.parse(uri) end 这将覆盖默认的carrierwave url 解析器,我认为这是错误的。您可以在此处阅读有关此问题的更多信息github.com/carrierwaveuploader/carrierwave/issues/700

标签: ruby-on-rails amazon-s3 carrierwave fog


【解决方案1】:

最好使用 v4 签名,应该可以防止这种错误。只需在 url_for 调用中添加选项“signature_version: :v4”即可。

temp_url = AWS::S3::S3Object.url_for(
  s3_key,
  S3_CONFIG['bucket'],
  use_ssl: true,
  signature_version: :v4)

【讨论】:

    【解决方案2】:

    FogExcon 有问题。

    请参阅 this answer 了解如何修复它并切换到使用实际 aws-sdk 的更好解决方案。


    库 --- 磁盘空间 --- 代码行 --- 启动时间 --- 运行时部门 --- 开发部门

    雾 --- 28.0M --- 133469 --- 0.693 --- 9 --- 11

    aws-sdk --- 5.4M --- 90290 --- 0.098 --- 3 --- 8*

    【讨论】: