我在我的服务器上使用s3.createPresignedPost()
生成一个AWS S3预签名的post对象,然后我尝试使用预签名的post url & fields从客户端直接上传一个文件到S3 bucket,但是得到了一个403 Forbidden
。
我尝试手动将表单域添加到FormData对象中,以直接匹配以下示例:https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-post-example.html,但继续收到403错误。
用于生成post对象的服务器端函数
const AWS = require("aws-sdk/global");
const S3 = require("aws-sdk/clients/s3");
const uuidv4 = require("uuid/v4");
AWS.config.update({
accessKeyId: process.env.S3_KEY_ID,
secretAccessKey: process.env.S3_SECRET_KEY,
region: "us-east-1"
});
const s3 = new S3();
const getPresignedPostData = (bucket, directory) => {
const key = `${directory}/${uuidv4()}`;
const postData = s3.createPresignedPost({
Bucket: bucket,
Fields: { Key: key, success_action_status: "201" },
Conditions: [{ acl: "public-read" }],
ContentType: "image/*",
Expires: 300
});
return postData;
};
返回类似于以下内容的内容:
{
fields: {
Key: "5cd880a7f8b0480b11b9940c/86d5552b-b713-4023-9363-a9b36130a03f"
Policy: {Base64-encoded policy string}
X-Amz-Algorithm: "AWS-HMAC-SHA256"
X-Amz-Credential: "AKIAI4ELUSI2XMHFKZOQ/20190524/us-east-1/s3/aws4_request"
X-Amz-Date: "20190524T200217Z"
X-Amz-Signature: "2931634e9afd76d0a50908538798b9c103e6adf067ba4e60b5b54f90cda49ce3"
bucket: "picture-perfect-photos"
success_action_status: "201"
},
url: "https://s3.amazonaws.com/picture-perfect-photos"
}
我的客户端函数如下所示:
const uploadToS3 = async ({ fields, url }, file) => {
const formData = new FormData();
Object.keys(fields).forEach(key => formData.append(key, fields[key]));
formData.append("file", file);
try {
const config = {
method: "POST",
body: formData
};
const response = await fetch(url, config);
if (!response.ok) {
throw new Error(response.statusText);
}
const data = await response.json();
return data;
} catch (err) {
console.log(err.message);
}
};
我的S3铲斗CORS配置如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>POST</AllowedMethod>
<AllowedMethod>PUT</AllowedMethod>
<AllowedMethod>DELETE</AllowedMethod>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>
我希望得到设置success_action_status: "201"
时发送的XML文档,但是不断得到403 Forbidden
2条答案
按热度按时间guicsvcw1#
我刚经历过同样的问题。
将
<AllowedMethod>PUT</AllowedMethod>
和<AllowedHeader>Content-*</AllowedHeader>
添加到S3控制台中S3桶的CORS规则中。向服务器发出发布请求以获取预先签名的S3 URL。发布请求的正文中应包含文件名和mime类型:
快递路线:
选择要上载的文件时异步函数中的客户端代码:
我的致命错误是在上传带有签名URL的文件时,在
uploadOptions
中添加了冗余的头文件。我遇到了其他线程,它们声称我必须显式地添加“Content-Type”头文件:但这在我的情况下是完全不必要的,这就是我得到403错误的原因。
idv4meu82#
这个线程上唯一的其他答案是谈论完全不同的API调用。
有2个相似但不同的API:
我自己也需要
createPresignedPost
,以前也用过getSignedUrl
,因为我想限制上传的文件大小,比AWS S3支持的要小得多。在我的例子中,我让用户上传图像。最大10MB。当上传来自客户端时,我需要限制文件上传大小的方法。如果你在这种情况下搜索,人们建议删除已经上传的大文件,但我不喜欢让上传开始。因此,在使用实际的
createPresignedPost
API调用时,您不仅会返回url
,还会返回fields
。字段是具有键值对的对象。
在客户端,您需要:
发送POST请求到url(
getSignedUrl
需要PUT代替)和所有你得到的域,你必须提供作为表单的域。只有额外的表单域被称为file
,这是你把你上传的文件。这里是样本PostMan截图与所有表格归档: