我在节点中使用aws-sdk
让我的 webapp 与 aws s3 存储桶通信。一段时间以来首次尝试将文件上传到 s3 时,它会失败;如果我尝试立即再次上传,它可以工作。
经过一些调试,似乎requestUrl
有问题:
第一次试用尝试将请求直接发送到
requestUrl: https://s3-ap-southeast-2.amazonaws.com/
,
这当然会导致403禁止错误。
其他成功的请求以
requestUrl: https://my-bucket.s3-ap-southeast-2.amazonaws.com/querystrings....
这是正确的网址。
现在我的问题是,为什么只有第一次审判会出错requestUrl
?在服务器中,签名 url 生成为:
const s3 = new AWS.S3({
params: {
Bucket: "my-bucket",
},
});
s3.getSignedUrl('putObject', {
Key: s3Key,
ContentType: newFile.type,
ACL: 'private',
})
顺便说一句,s3 存储桶的凭证会自动从ec2
服务器的IAM role
加载,并且存储桶设置为允许该角色GET
和PUT
。
虽然我不能肯定地说这是问题所在,但文档中有一个警告,特别提到了 IAM 角色:
注意:如果同步调用此方法(无回调),则必须确保您具有静态或以前解析的凭据,否则它可能无法正确签署请求。如果您无法保证这一点(您使用的是异步凭证提供程序,即 EC2 IAM 角色),则应始终使用异步回调调用此方法。
http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#getSignedUrl-property
这将在后续运行中自行解决是有意义的,因为获取角色凭据的异步尝试可能会在第二次调用时在后台成功。