Amazon web services AWS预签名URL PutObject错误:SignatureDesNotMatch
我使用这段代码生成了一个SignedURL,它可以正常工作Amazon web services AWS预签名URL PutObject错误:SignatureDesNotMatch,amazon-web-services,amazon-s3,aws-lambda,aws-sdk,pre-signed-url,Amazon Web Services,Amazon S3,Aws Lambda,Aws Sdk,Pre Signed Url,我使用这段代码生成了一个SignedURL,它可以正常工作 const AWS = require('aws-sdk'); const s3AccessKeyId = "<my access key id>"; const s3SecretAccessKey = "<my secret access key>"; const bucketName = "<my bucket name>"; AWS.config.update({ accessKeyId
const AWS = require('aws-sdk');
const s3AccessKeyId = "<my access key id>";
const s3SecretAccessKey = "<my secret access key>";
const bucketName = "<my bucket name>";
AWS.config.update({
accessKeyId: s3AccessKeyId,
secretAccessKey: s3SecretAccessKey,
region: 'eu-west-1',
signatureVersion: 'v4'
});
const s3 = new AWS.S3();
const isTokenInvalid = function (token) {
// token validation is needed
return token === undefined;
}
const response = function (code, body) {
return {
"statusCode": code,
"headers": {'Access-Control-Allow-Origin': '*'},
"body": body,
"isBase64Encoded": false
}
}
function buildDownloadParams(bucketName, key, expires) {
return {
Bucket: bucketName,
Key: key,
Expires: expires
}
}
function buildUploadParams(bucketName, key, body, expires) {
return {
Bucket: bucketName,
Key: key,
ContentType: 'text/plain',
ACL: 'bucket-owner-full-control',
Body: body,
Expires: expires
}
}
exports.handler = (event, context, callback) => {
const token = event.queryStringParameters["token"];
if (isTokenInvalid(token)) {
callback(null, response(401, "The token is not provided or is invalid."));
return;
}
const action = event.queryStringParameters["action"];
let operation;
let params;
if (action === 'download') {
operation = 'getObject';
params = buildDownloadParams(bucketName, 'video.mp4', 60);
} else if (action === 'upload') {
operation = 'putObject';
params = buildUploadParams(bucketName, 'test.txt', 'hello world', 120);
} else {
callback(null, response(400, "ERROR: invalid action '" + action + "'"));
return;
}
const preSignedGetUrl = s3.getSignedUrl(operation, params);
callback(null, response(200, preSignedGetUrl));
};
这些是AWS 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>PUT</AllowedMethod>
<AllowedMethod>POST</AllowedMethod>
<MaxAgeSeconds>3000</MaxAgeSeconds>
<AllowedHeader>Authorization</AllowedHeader>
</CORSRule>
</CORSConfiguration>
*
得到
放
邮递
3000
授权
我浏览了StackOverflow的所有其他相关帖子,并修复了他们提到的可能的解决方案,例如添加区域、signatureVersion和ACL。但是它仍然不起作用。第一个也是最明显的错误是,您根本没有发出
PUT
请求。根据错误响应中显示的
,您正在发出一个GET
请求。这确实很奇怪。但是,即使我硬编码putObject请求,它也会返回/GETBackground:请求方法(例如,GET
或PUT
)没有编码到签名的URL中。您确实必须使用适当的参数对URL进行签名,以匹配您将发出的请求,但是使用putObject
,因为该操作仅告诉SDK HTTP客户端在实际发出请求时将使用什么方法。粘贴到浏览器地址栏上的方法总是GET
。要测试PUT
,您需要像Curl或Postman这样的工具。
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>PUT</AllowedMethod>
<AllowedMethod>POST</AllowedMethod>
<MaxAgeSeconds>3000</MaxAgeSeconds>
<AllowedHeader>Authorization</AllowedHeader>
</CORSRule>
</CORSConfiguration>