Upload error: Upload error: 403 — `SignatureDoesNotMatch `
gastongouron opened this issue · comments
Hello, and thank you for the amazing piece of code react-s3-uploader
seems to be. I'm sorry in advance if this issue is code related but after stumbling for a few days agains this and reading every possible issue on the list, here i am.
The context:
- Rails 5 api backend using
'aws-sdk', '~> 3'
gem to talk to S3 - ReactJS client using
react-s3-uploader
So far, everything seems to work out of the box. Here is the method that returns the presignedUrl
in rails controller by using the filename
parameter:
# S3_controller#sign
def sign
filename = params["objectName"]
content = params["contentType"]
signer = Aws::S3::Presigner.new
signed = signer.presigned_url(:put_object,
bucket: 'encorencore',
key: "uploads/#{filename}",
acl: 'public-read',
content_type: content)
render json: { signedUrl: signed }
end
I have been uploading successfully files to amazon with this backend for the sake of testing so I'm most likely certain that this issue is not related to credentials. Meanwhile, On the frontend, I use the ReactS3Uploader
with the following props:
<ReactS3Uploader
signingUrl={`/s3/presigned_url`}
signingUrlMethod="GET"
accept="image/*"
s3path="/uploads"
preprocess={this.onUploadStart}
onSignedUrl={this.onSignedUrl}
onProgress={this.onUploadProgress}
onError={this.onUploadError}
onFinish={this.onUploadFinish}
signingUrlHeaders={ this.headers }
// signingUrlQueryParams={{ additional: query-params }}
signingUrlWithCredentials={ true }
uploadRequestHeaders={{ 'x-amz-acl': 'public-read' }} // this is the default
contentDisposition="auto"
scrubFilename={(filename) => filename.replace(/[^\w\d_\-.]+/ig, '')}
inputRef={cmp => this.uploadInput = cmp}
autoUpload={true}
/>
What happens:
- Client updates a file
- rails gets called with the filename
- rails calls amazon through the gem and creates the signed_url
- rails replies to the client with JSON whose payload contains
{ signedUrl: the_url }
- client gets the url and starts an OPTION call to amazon that results in 200
- The error: clients sends a put to amazon with the file data and get a 403.
Here is a preview of what it looks like in my browser:
When I manually visit the put url provided by the server I'm reaching a web page with some XML, the message show the following error:
Right now, I'm not sure where the problem comes from and the amazon error message is not specific enough for me to understand if the problem comes from the backend signature (as the message suggests), or from the client props, or event worse from S3 bucket setup itself.
What I have tried without success:
- Updating the CORS config of this bucket such as:
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>HEAD</AllowedMethod>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>PUT</AllowedMethod>
<AllowedMethod>POST</AllowedMethod>
<AllowedMethod>DELETE</AllowedMethod>
<ExposeHeader>ETag</ExposeHeader>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>
-2. Updating the bucket policy (also tried with a wildcard for Principal with same results):
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1540188247000",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::707682590005:root"
},
"Action": "s3:*",
"Resource": "arn:aws:s3:::encorencore/*"
}
]
}
-3. tweeking every possible option on both rails and react.
I'm not loosing hope but I secretly wish someone encountered a similar problem in a similar context and can come up with a solution or some sort of thing I wouldn't have though about. Please, if you have any input, do not hesitate!
Thanks a lot for your time <3
dupe; see comment on #191