2

I am using ng-file-upload to upload a photo to S3. I have tested my S3 bucket and my policy/signature generator with the ng-file-upload demo tool and have successfully used it to upload the photo to my bucket.


Edit: A key difference seems to be the addition of a header:

Authorization:Token 3j4fl8jk0lqfkj4izj2w3ljfopljlwep1010notreal

That is present in my code but not in the demo page. Perhaps it's my angular app.


Installed through bower, took the relevant components, tried to upload a file, and get an error that looks like this:

 400: <?xml version="1.0" encoding="UTF-8"?> 
 <Error>
 <Code>InvalidArgument</Code> 
 <Message>Unsupported Authorization Type</Message> 
 <ArgumentName>Authorization</ArgumentName>
 <ArgumentValue>Token 3j4fl8jk0lqfkj4izj2w3ljfopljlwep1010notreal</ArgumentValue>
 <RequestId>F1F5FK-not-real-81FED9CA</RequestId>
 <HostId>CQEW98p3D2e+pVz-not-real-codeu28m7asqpGjagL3409gj3f4kijKJpofk</HostId>
 </Error>

Searching around, I've noted many 400 Errors but not many cases with the ArgumentValue as Token [some-code-here].

Looking at AWS documentation, InvalidArgument is a bit opaque for someone rather new to AWS.

And here is the policy that I'm encoding (Python):

#exptime = '2100-07-31T06:23:35Z' #for debugging
policy_document = {"expiration": exptime,
    "conditions": [ 
      {"bucket": settings.AWS_STORAGE_BUCKET_NAME}, 
      ["starts-with", '$key', ""],
      {"acl": "private"},
      ["starts-with", "$Content-Type", ""],
      ["starts-with", "$filename", ""],
      ["content-length-range", 0, 5000000] 
    ]
  }

To reiterate, this policy with the aforementioned demo worked, so I expect a problem on my front-end implementation:

$scope.upload = function(file) {
    file.upload = Upload.upload({
                url: 'https://mybucket.s3-us-west-2.amazonaws.com',
                method: 'POST',
                fields: {
                    key: file.name,
                    AWSAccessKeyId: myAccessKeyId,
                    acl: 'private',
                    policy: myPolicyEncoded,
                    signature: mySignatureEncoded,
                    "Content-Type": file.type === null || 
                        file.type === '' ? 'application/octet-stream' : file.type,
                    filename: file.name
                },
                file: file
            });
}

2 Answers 2

6

Took me a while to find it, but as my edit pointed out, looking into the request header a token used in the Angular app's login/auth process was being sent as a default, and Amazon's service didn't like that. Removing the header in the http request for this specific case solved the issue.

The upload service on my front-end thus looks like:

$scope.upload = function(file) {
    file.upload = Upload.upload({
                url: 'https://mybucket.s3-us-west-2.amazonaws.com',
                method: 'POST',
                fields: {
                    key: file.name,
                    AWSAccessKeyId: myAccessKeyId,
                    acl: 'private',
                    policy: myPolicyEncoded,
                    signature: mySignatureEncoded,
                    "Content-Type": file.type === null || 
                        file.type === '' ? 'application/octet-stream' : file.type,
                    filename: file.name
                },
                headers: {
                    'Authorization': undefined
                },
                file: file
            });
}
Sign up to request clarification or add additional context in comments.

1 Comment

After 3 hours, this answer did the job!
0

This is an old thread, but i just came to this error.

Instead of removing the custom header you could put that header in the CORS Policy like:

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
    <AllowedOrigin>*</AllowedOrigin>
    <AllowedMethod>POST</AllowedMethod>
    <AllowedMethod>PUT</AllowedMethod>
    <MaxAgeSeconds>3000</MaxAgeSeconds>
    <AllowedHeader>Authorization</AllowedHeader>
</CORSRule>
</CORSConfiguration>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.