上载到AWS S3时无效的日期

时间:2016-03-07 14:16:40

标签: amazon-web-services amazon-s3

我正在尝试通过putObject和预先签名的网址将图片上传到S3。

以下是我在生成预签名网址时提供的网址:

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

当我尝试通过PUT上传文件时,AWS会回复:

<?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>

以下是我正在使用的请求的卷曲版本:

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>"

由于时间戳是由AWS生成的,因此它应该是正确的。我已经尝试将其更改为包含小数并得到相同的错误。

问题可能与我在请求中上传文件有关吗?

更新 - 添加用于生成签名网址的代码

通过AWS Javascript SDK生成签名的URL:

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)
  })
})

我的访问密钥和密钥通过环境变量加载为AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY

2 个答案:

答案 0 :(得分:0)

你只是被糟糕的文档所困扰。似乎与此链接有关

Amazon S3 invalid date when using expires in url_for

整数是&#34; (指定当前时间之后的秒数)&#34;。 由于您在纪元(0 = 1970-1-1)中输入时间,因此它是当前纪元时间+您的时间,46 + 46年= 92年。对于s3来说似乎是疯狂的有效期。

答案 1 :(得分:0)

Amazon S3仅支持签名网址中的32位时间戳:

2147483647 是您可以拥有的最大时间戳。

我将来会创建20年的时间戳,这会破坏我签名的网址。使用小于2,147,483,647的值可以解决问题。

希望这有助于某人!