AWS S3 - PUT 到 URL 从 getSignedUrl() returns 403 SignatureDoesNotMatch 错误
AWS S3 - PUT to URL from getSignedUrl() returns 403 SignatureDoesNotMatch error
这个问题已经困扰我两天了。
objective: 通过 getSignedUrl 函数提供的 pre-signed URL 将图像直接从浏览器上传到 S3 AWS Javascript SDK.
我在使用 getSignedUrl 生成 URL 时没有遇到任何问题。以下代码...
const params = {
Key: key,
Bucket: process.env.S3_BUCKET,
ContentType: "image/jpeg"
};
S3.getSignedUrl("putObject", params, callback);
...产生如下内容:
https://s3.amazonaws.com/foobar-bucket/someImage.jpeg?AWSAccessKeyId=ACCESSKEY123&Content-Type=image%2Fjpeg&Expires=1543357053&Signature=3fgjyj7gpJiQvbIGhqWXSY40JUU%3D&x-amz-acl=private&x-amz-security-token=FQoGZXIvYXdzEDYaDPzeqKMbfgetCcZBaCL0AWftL%2BIT%2BP3tqTDVtNU1G8eC9sjl9unhwknrYvnEcrztfR9%2FO9AGD6VDiDDKfTQ9SmQpfXmiyTKDwAcevTwxeRnj6hGwnHgvzFVBzoslrB8MxrxjUpiI7NQW3oRMunbLskZ4LgvQYs8Rh%2FDjat4H%2F%2BvfPxDSQUSa41%2BFKcoySUHGh2xqfBFGCkHlIqVgk1KELDHmTaNckkvc9B4cgEXmAd3u1f1KC9mbobYcLLRPIzMj9bLJH%2BIlINylzubao1pCQ7m%2BWdX5xAZDhTSNwQfo4ywSWV7kUpbq2dgEriOiKAReEjmFQtuGqYBi3t2dhrasptOlXFXUozdz23wU%3D
但是通过 PUT 请求将图像上传到提供的 URL 总是 returns 来自 S3 的 403 SignatureDoesNotMatch
错误。
有效的方法:
- 从 AWS Lambda 的本地实例调用 getSignedUrl()(通过 serverless-offline)。
什么不起作用:
- 将查询字符串变量设置为headers(Content-Type、x-amz-*等)
- 正在删除所有 headers
- 获取 URL 时更改 ACL(私有、public-read-write、无 ACL 等)
- 更改节点
aws-sdk
中的区域
- 尝试 POST 而不是 PUT(值得一试)
如能就此问题提供任何帮助,我们将不胜感激。如果这仍然是一个问题,我打算把我的电脑扔出 window,然后沮丧地跳出去,因为它根本不想工作!
我明白了。调用 getSignedUrl() 的 Lambda 函数没有访问相关 S3 存储桶的正确 IAM 角色权限。在 serverless.yml...
iamRoleStatements:
- Effect: Allow
Action:
- s3:*
Resource: "arn:aws:s3:::foobar-bucket/*"
我实际上不会在这里使用通配符,但您明白了。 getSignedUrl() 仍然成功 并且 returns 和 URL 即使 URL 由于缺少权限而注定要失败,这一事实极具误导性。
希望这个回答能对以后迷茫的人有所帮助。
它以老派的方式对我有用:(axios 一直给出 403 Forbidden)
const xhr = new XMLHttpRequest();
xhr.open("PUT", signedRequest);
xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
//Put your logic here..
//When it get's here you can access the image using the url you got when signed.
}
}
};
xhr.send(file);
请注意,这需要从客户端 运行 进行,因此您需要在存储桶中配置 Cross Origin Police。
这个问题已经困扰我两天了。
objective: 通过 getSignedUrl 函数提供的 pre-signed URL 将图像直接从浏览器上传到 S3 AWS Javascript SDK.
我在使用 getSignedUrl 生成 URL 时没有遇到任何问题。以下代码...
const params = {
Key: key,
Bucket: process.env.S3_BUCKET,
ContentType: "image/jpeg"
};
S3.getSignedUrl("putObject", params, callback);
...产生如下内容:
https://s3.amazonaws.com/foobar-bucket/someImage.jpeg?AWSAccessKeyId=ACCESSKEY123&Content-Type=image%2Fjpeg&Expires=1543357053&Signature=3fgjyj7gpJiQvbIGhqWXSY40JUU%3D&x-amz-acl=private&x-amz-security-token=FQoGZXIvYXdzEDYaDPzeqKMbfgetCcZBaCL0AWftL%2BIT%2BP3tqTDVtNU1G8eC9sjl9unhwknrYvnEcrztfR9%2FO9AGD6VDiDDKfTQ9SmQpfXmiyTKDwAcevTwxeRnj6hGwnHgvzFVBzoslrB8MxrxjUpiI7NQW3oRMunbLskZ4LgvQYs8Rh%2FDjat4H%2F%2BvfPxDSQUSa41%2BFKcoySUHGh2xqfBFGCkHlIqVgk1KELDHmTaNckkvc9B4cgEXmAd3u1f1KC9mbobYcLLRPIzMj9bLJH%2BIlINylzubao1pCQ7m%2BWdX5xAZDhTSNwQfo4ywSWV7kUpbq2dgEriOiKAReEjmFQtuGqYBi3t2dhrasptOlXFXUozdz23wU%3D
但是通过 PUT 请求将图像上传到提供的 URL 总是 returns 来自 S3 的 403 SignatureDoesNotMatch
错误。
有效的方法:
- 从 AWS Lambda 的本地实例调用 getSignedUrl()(通过 serverless-offline)。
什么不起作用:
- 将查询字符串变量设置为headers(Content-Type、x-amz-*等)
- 正在删除所有 headers
- 获取 URL 时更改 ACL(私有、public-read-write、无 ACL 等)
- 更改节点
aws-sdk
中的区域 - 尝试 POST 而不是 PUT(值得一试)
如能就此问题提供任何帮助,我们将不胜感激。如果这仍然是一个问题,我打算把我的电脑扔出 window,然后沮丧地跳出去,因为它根本不想工作!
我明白了。调用 getSignedUrl() 的 Lambda 函数没有访问相关 S3 存储桶的正确 IAM 角色权限。在 serverless.yml...
iamRoleStatements:
- Effect: Allow
Action:
- s3:*
Resource: "arn:aws:s3:::foobar-bucket/*"
我实际上不会在这里使用通配符,但您明白了。 getSignedUrl() 仍然成功 并且 returns 和 URL 即使 URL 由于缺少权限而注定要失败,这一事实极具误导性。
希望这个回答能对以后迷茫的人有所帮助。
它以老派的方式对我有用:(axios 一直给出 403 Forbidden)
const xhr = new XMLHttpRequest();
xhr.open("PUT", signedRequest);
xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
//Put your logic here..
//When it get's here you can access the image using the url you got when signed.
}
}
};
xhr.send(file);
请注意,这需要从客户端 运行 进行,因此您需要在存储桶中配置 Cross Origin Police。