javascript - AWS S3 Post InvalidPolicydocument 错误:无效的简单条件
问题描述
我正在尝试直接发布到我的 S3 存储桶,并且今天一整天都收到此 400 错误。
<Error>
<Code>InvalidPolicyDocument</Code>
<Message>Invalid Policy: Invalid Simple-Condition: Simple-Conditions must have exactly one property specified.</Message>
<RequestId>6M9N0SAH7K6W9GCJ</RequestId>
<HostId>6naRbfGG7xVW3hgMSkdnGU6byAtFgEStBL57MdxquKefVNUr/MDP1JWleiQtvPmcgQIilJXnRjc=</HostId>
</Error>
根据文档和我所做的所有搜索,这似乎是政策不匹配的问题?
这是创建Formdata
对象的前端 Javascript 代码fd
:(httpResponseData 是来自我的服务器的响应,包括所有编码的策略和签名等。)
let fd = new FormData();
fd.append("bucket", httpResponseData.bucket)
fd.append("acl", httpResponseData.bucketAcl);
fd.append("key", file.name);
fd.append("Content-Type", file.type);
fd.append("policy", httpResponseData.encodedPolicy);
fd.append("x-amz-algorithm", "AWS4-HMAC-SHA256");
fd.append("x-amz-credential", httpResponseData.amzCred);
fd.append("x-amz-date", httpResponseData.expirationStrClean);
fd.append("x-amz-meta-type", "post-image");
fd.append("x-amz-signature", httpResponseData.sign);
fd.append("file", file);
这是我在后端定义的政策条件:
const s3Policy = {
expiration: this.expirationStr,
conditions: [
{ bucket: this.bucket },
["starts-with", "$key", ""], // allows any file name
{ acl: this.bucketAcl },
["starts-with", "$Content-Type", "image/"],
{ "x-amz-algorithm": "AWS4-HMAC-SHA256" },
{ "x-amz-credential": this.amzCred },
{ "x-amz-date": this.expirationStrClean },
{ "x-amz-meta-type": "post-image" }
],
};
this
指的是被实例化的特定对象(显然)。我正在执行这样的签名策略对象的制作:
const crypto = require("crypto");
const AccessKeyId = "My Access Key ID";
const SecretAccessKey = "My Secret Access Key";
const regionName = "My Region";
class S3SignedPolicy {
constructor() {
this.bucket = "forecast-post-images";
this.bucketAcl = "public-read";
this.expirationStr = this.constructor.createExpDate();
this.expirationStrClean = this.expirationStr.split(/[:\-.]/g).join("");
this.amzCred = this.constructor.createAMZCred(this.expirationStrClean);
this.encodedPolicy = this.constructor.createEncodedPolicy();
this.sign = this.constructor.createSignedPolicy(this.encodedPolicy, this.expirationStrClean);
}
static createExpDate() {
let expirationDate = new Date();
console.log("called", expirationDate.toLocaleTimeString());
expirationDate.setMinutes(expirationDate.getMinutes() + 20);
const expirationStr = expirationDate.toISOString();
// const expirationStrClean = expirationStr.split(/[:\-.]/g).join("");
return expirationStr;
}
static createAMZCred(cleanISOString) {
const YYYYMMDD = cleanISOString.slice(0, 8);
const amzCred = AccessKeyId + "/" + YYYYMMDD + "/" + regionName + "/s3/aws4_request";
return amzCred;
}
static createSignedPolicy(encodedPolicy, cleanISOString) {
let YYYYMMDD = cleanISOString.slice(0, 8);
const kDate = crypto
.createHmac("sha256", "AWS4" + SecretAccessKey)
.update(YYYYMMDD)
.digest("");
const kRegion = crypto.createHmac("sha256", kDate).update(regionName).digest("");
const kService = crypto.createHmac("sha256", kRegion).update("s3").digest("");
const kSigning = crypto.createHmac("sha256", kService).update("aws4_request").digest("");
const sign = crypto.createHmac("sha256", kSigning).update(encodedPolicy).digest("hex");
return sign;
}
static createEncodedPolicy() {
const s3Policy = {
expiration: this.expirationStr,
conditions: [
{ bucket: this.bucket },
["starts-with", "$key", ""], // allows any file name
{ acl: this.bucketAcl },
["starts-with", "$Content-Type", "image/"],
{ "x-amz-algorithm": "AWS4-HMAC-SHA256" },
{ "x-amz-credential": this.amzCred },
{ "x-amz-date": this.expirationStrClean },
{ "x-amz-meta-type": "post-image" }
],
};
let encodedPolicy = Buffer.from(JSON.stringify(s3Policy)).toString("base64");
return encodedPolicy;
}
}
请指出我是否在这里遗漏了什么或做错了什么。
解决方案
原来这不是 AWS 问题,而是我这边的 Javascript 错误。
在我的S3SignedPolicy
类中,我已经声明了所有函数,static
因此当我this.anything
在它们内部调用时,它们将返回undefined
,因为this
这里指的是 Class ( Function S3SignedPolicy
) 而不是创建的单个对象。
因此,我的policy
字符串无效。
推荐阅读
- tomcat - 在辅助路由中将 tomcat 应用程序重定向到 https
- quicksort - 快速排序算法的堆缓冲区溢出错误
- gtk - XML 不能用作墙纸使用 org.freedesktop.portal.Wallpaper Portal [Vala]
- c - Flex & Bison:“真”被解释为和 ID
- java - 在多个页面上打印 javafx WebEngine 的内容
- scala - 导入后值 reduceByKey 不是 org.apache.spark.rdd.RDD[(Int, Int)] 的成员
- python - 谷歌 colab 缓存谷歌驱动器内容
- javascript - 在 JavaScript 中更新
- javascript - Electron 版本 12 错误:未捕获错误:找不到模块
- machine-learning - 如何将回归模型转换为分类模型