unlikely_monkey
unlikely_monkey

Reputation: 183

Invalid Date When Uploading to AWS S3

I'm trying to upload an image to S3 via putObject and a pre-signed URL.

Here is the URL that was provided when I generated the pre-signed URL:

https://<myS3Bucket>.s3.amazonaws.com/1ffd1c88-5661-48f9-a135-04bd569614dd.jpg?AWSAccessKeyId=<accessKey>&Expires=1458177431311&Signature=<signature>-amz-security-token=<token>

When I attempt to upload the file via a PUT, AWS responds with:

<?xml version="1.0" encoding="UTF-8"?>
<Error>
    <Code>AccessDenied</Code>
    <Message>Invalid date (should be seconds since epoch): 1458177431311</Message>
    <RequestId>...</RequestId>
    <HostId>...</HostId>
</Error>

Here is the curl version of the request I was using:

curl -X PUT -H "Cache-Control: no-cache" -H "Postman-Token: 78e46be3-8ecc-   4156-be3d-7e2f4688a127" -H "Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW" -F "file=@[object Object]" "https://<myS3Bucket>.s3.amazonaws.com/1ffd1c88-5661-48f9-a135-04bd569614dd.jpg?AWSAccessKeyId=<accessKey>&Expires=1458177431311&Signature=<signature>-amz-security-token=<mySecurityToken>"

Since the timestamp is generated by AWS, it should be correct. I have tried changing it to include decimals and got the same error.

Could the problem be in the way I'm uploading the file in my request?

Update - Add code for generating the signed URL

The signed URL is being generated via the AWS Javascript SDK:

var AWS = require('aws-sdk')
var uuid = require('node-uuid')
var Promise = require('bluebird')

var s3 = new AWS.S3()
var params = {
  Bucket: bucket,  // bucket is stored as .env variable
  Key: uuid.v4() + '.jpg' // file is always a jpg
}

return new Promise(function (resolve, reject) {
  s3.getSignedUrl('putObject', params, function (err, url) {
    if (err) {
      reject(new Error(err))
    }
    var payload = { url: url }
    resolve(payload)
  })
})

My access key and secret key are loaded via environment variables as AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY.

Upvotes: 2

Views: 4931

Answers (2)

Fostah
Fostah

Reputation: 2946

Amazon S3 only supports 32 bit timestamps in signed urls:

2147483647 is the largest timestamp you can have.

I was creating timestamps 20 years in the future and it was breaking my signed URL's. Using a value less than 2,147,483,647 fixes the issue.

Hope this helps someone!

Upvotes: 2

mootmoot
mootmoot

Reputation: 13176

You just get bitten by bad documentation. Seems relate to this link

Amazon S3 invalid date when using expires in url_for

The integer are mean for " (to specify the number of seconds after the current time)". Since you enter the time in epoch(0 = 1970-1-1), So it is current epoch time + your time, 46+46 years= 92 years. Appear to be crazy expiration period for s3.

Upvotes: 0

Related Questions