我正在尝试通过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_ID
和AWS_SECRET_ACCESS_KEY
。
答案 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的值可以解决问题。
希望这有助于某人!