Rails 6 Amazon S3 Error POST 403 (Forbidden) using s3_direct



我已经重写了2个应用程序,使用旧版本的Rails v3.2和4.2到当前的Rails 6.1.4.1在这两个应用程序的情况下,我有一切正常工作,除了图片上传。起初,我无法使s3_direct_upload正常工作。现在它似乎正在工作,我得到的进度条开始,但我得到这个可恶的POST 403(禁止)错误(它有在错误中间的URL)。s3_direct_upload gem基本上只是打包了jQuery-file-upload gem,以便在查看其源代码后更容易实现。

https://github.com/waynehoover/s3_direct_upload

在我的情况下,奇怪的是我知道这不是一个CORS问题,因为我使用的是非常相同的桶,键和所有的东西,目前仍然在这些应用程序的原始版本中工作,仍然在Heroku上工作。代码几乎是一样的,唯一的变化是Rails的新版本。两者都给出了完全相同的错误。在这两个应用程序中,我都可以很好地查看图片。IT可以使用相同的键ID和其他所有内容访问桶。

然后我尝试并制作了一个使用jQuery-file-upload gem(与s3_direct_upload gem分开)的示例应用程序,因为我想验证是否它是导致问题的s3_direct_upload gem或如果它是导致问题的jQuery-file-upload gem。

https://github.com/railscasts/383-uploading-to-amazon-s3/tree/master/gallery-jquery-fileupload

我做了一个Rails 6版本的这个应用程序,并得到了它的所有工作和我的恐怖,它给了我完全相同的问题,后403(禁止)错误。
我想出了如何在应用程序的JavaScript部分启用console .log,并让它转储错误。

这是控制台的完整错误。(我把MYBUCKET放在桶名的地方)

VM3692:1 POST https://MYBUCKET.s3.amazonaws.com/ 403 (Forbidden)
(anonymous) @ VM3692:1
XMLHttpRequest.send @ includes.js?v=35a79b300ab5afa978cb59af0b05e059:839
send @ application-c24f8496b74e37ed951b517eb53daac49c7c8be5d2307e5af5413626d42a478c.js:10254
ajax @ application-c24f8496b74e37ed951b517eb53daac49c7c8be5d2307e5af5413626d42a478c.js:9738
send @ application-c24f8496b74e37ed951b517eb53daac49c7c8be5d2307e5af5413626d42a478c.js:13646
_onSend @ application-c24f8496b74e37ed951b517eb53daac49c7c8be5d2307e5af5413626d42a478c.js:13708
(anonymous) @ application-c24f8496b74e37ed951b517eb53daac49c7c8be5d2307e5af5413626d42a478c.js:12078
data.submit @ application-c24f8496b74e37ed951b517eb53daac49c7c8be5d2307e5af5413626d42a478c.js:13414
add @ application-c24f8496b74e37ed951b517eb53daac49c7c8be5d2307e5af5413626d42a478c.js:14375
_trigger @ application-c24f8496b74e37ed951b517eb53daac49c7c8be5d2307e5af5413626d42a478c.js:12478
(anonymous) @ application-c24f8496b74e37ed951b517eb53daac49c7c8be5d2307e5af5413626d42a478c.js:13777
each @ application-c24f8496b74e37ed951b517eb53daac49c7c8be5d2307e5af5413626d42a478c.js:370
_onAdd @ application-c24f8496b74e37ed951b517eb53daac49c7c8be5d2307e5af5413626d42a478c.js:13770
(anonymous) @ application-c24f8496b74e37ed951b517eb53daac49c7c8be5d2307e5af5413626d42a478c.js:12078
(anonymous) @ application-c24f8496b74e37ed951b517eb53daac49c7c8be5d2307e5af5413626d42a478c.js:13975
fire @ application-c24f8496b74e37ed951b517eb53daac49c7c8be5d2307e5af5413626d42a478c.js:3232
add @ application-c24f8496b74e37ed951b517eb53daac49c7c8be5d2307e5af5413626d42a478c.js:3291
always @ application-c24f8496b74e37ed951b517eb53daac49c7c8be5d2307e5af5413626d42a478c.js:3400
_onChange @ application-c24f8496b74e37ed951b517eb53daac49c7c8be5d2307e5af5413626d42a478c.js:13965
(anonymous) @ application-c24f8496b74e37ed951b517eb53daac49c7c8be5d2307e5af5413626d42a478c.js:12078
handlerProxy @ application-c24f8496b74e37ed951b517eb53daac49c7c8be5d2307e5af5413626d42a478c.js:12389
dispatch @ application-c24f8496b74e37ed951b517eb53daac49c7c8be5d2307e5af5413626d42a478c.js:5226
elemData.handle @ application-c24f8496b74e37ed951b517eb53daac49c7c8be5d2307e5af5413626d42a478c.js:4878
application-c24f8496b74e37ed951b517eb53daac49c7c8be5d2307e5af5413626d42a478c.js:14438 Upload failed:
application-c24f8496b74e37ed951b517eb53daac49c7c8be5d2307e5af5413626d42a478c.js:14439 
abort: ƒ ()
add: ƒ (e, data)
autoUpload: true
bitrate: 1645390.4761904762
bitrateInterval: 500
blob: null
cache: false
contentType: false
context: jQuery.fn.init [div#upload_eq38hayegan.upload]
create: null
data: FormData {}
disabled: false
done: ƒ (e, data)
dropZone: jQuery.fn.init [div#before-pictures-dropzone.well.dropzone, context: document, selector: '#before-pictures-dropzone']
errorThrown: "Forbidden"
fail: ƒ (e, data)
fileInput: jQuery.fn.init [input#before_photo, context: input#before_photo]
fileInputClone: jQuery.fn.init [input#before_photo, prevObject: jQuery.fn.init(1), context: input#before_photo]
files: [File]
forceIframeTransport: false
form: jQuery.fn.init [form#attachment_before, context: form#attachment_before]
formAcceptCharset: "UTF-8"
formData: ƒ (form)
headers: {}
i18n: ƒ (message, context)
jqXHR: {readyState: 4, getResponseHeader: ƒ, getAllResponseHeaders: ƒ, setRequestHeader: ƒ, overrideMimeType: ƒ, …}
limitMultiFileUploadSizeOverhead: 512
loaded: 86383
messages: {uploadedBytes: 'Uploaded bytes exceed file size'}
multipart: true
originalFiles: [File]
paramName: ['file']
pasteZone: jQuery.fn.init {}
process: ƒ (resolveFunc, rejectFunc)
processData: false
processing: ƒ ()
progress: ƒ ()
progressInterval: 100
recalculateProgress: true
replaceFileInput: true
response: ƒ ()
sequentialUploads: false
singleFileUploads: true
start: ƒ (e)
state: ƒ ()
submit: ƒ ()
textStatus: "error"
timeout: 0
total: 86383
type: "POST"
uploadedBytes: 0
url: "https://MYBUCKET.s3.amazonaws.com/"
xhr: ƒ ()
_bitrateTimer: {_super: undefined, _superApply: undefined, timestamp: 1634768499443, loaded: 86383, bitrate: 1645390.4761904762, …}
_progress: {loaded: 86383, total: 86383, bitrate: 1645390.4761904762}
_response: {jqXHR: {…}, textStatus: 'error', errorThrown: 'Forbidden'}
_time: 1634768499443
[[Prototype]]: Object

我很想知道如何让这些应用程序在Rails 6中正常工作,如果可能的话,与现有的项目。如果没有,我甚至愿意听到潜在的替代品,最好是使用现有的回形针和amazon-sdk-v1或amazon-sdk gems。我只需要一些其他的东西来取代上传功能,但甚至愿意考虑一些东西,将做上述所有。这对我来说是一条更困难的路,因为我还是一个初学者。

我尝试了两个旧版本,如原始应用程序是在amazon-sdk-v1和amazon-sdk(版本3)中编写的。必须更新一些项目才能使v3工作。在这两种情况下,我都能看到照片,我只是不能上传。这个问题似乎被隔离到POST/UPLOAD功能和s3_direct_upload或jQuery-file-upload gems。我假设还有别的事情我必须做,让这些应用程序与Rails 6一起工作,我只是不知道它是什么。

如果有人想看到任何具体的东西请让我知道,我不知道该展示什么,而不只是展示我知道人们不欣赏的一切。

任何帮助将是感激的,谢谢你!斯科特

问题出在s3_direct_upload创建上传表单的方式上。它正在使用$utf8向表单添加一个部分,这显然在某些时候不再允许。在/app/lib/form_helper. js中的s3_direct_upload gem v0.1.7中。在方法def policy_data方法中,这一行必须从方法中删除:

["starts-with", "$utf8", ""],

从gem的本地副本中删除后,POST错误就会消失,并成功上传到Amazon S3。但是,这对本地副本没有任何帮助,而且显然不能将更改推送到Heroku或其他任何地方。

在对s3_direct_upload GIT存储库进行进一步检查后,我发现如果您将最新版本作为插件而不是作为gem拉出最新版本,有人会发现策略错误并修复它,他们也添加了一些更多的功能,但由于您还必须在file_field_tag中添加额外的选项。

这是你可以拉出Rails 6的GEM工作版本的方法

gem 's3_direct_upload', github: 'waynehoover/s3_direct_upload', ref: '6f6decc75fdf89888d7f729fc89f78e90d91cece'

如果你把它放在你的gemfile中,然后使用bundle install,它会转到GIT并把所有最新的更改拉到GEM中。如果你去寻找宝石的本地副本,它最终会把它放在一个稍微不同的地方。放在

下面
C:Ruby27-x64librubygems2.7.0bundlergems

代替:

C:Ruby27-x64librubygems2.7.0gems

最后,当你拉出这个最新版本时,你必须添加

data: { url: s3_uploader_url }

到file_field_tag的末尾例如我的是:

= file_field_tag(:file, id: "before_photo", multiple: true, data: { url: s3_uploader_url })

如果你拉最新版本,你添加data: {url: s3_uploader_url}到你的file_field_tag的末尾,你的s3_direct_upload应该开始正常工作。