AWS预签名URL PutObject错误:SignatureDoesNotMatch

时间:2019-09-27 10:01:00

标签: 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: 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));
};

当我使用PRE-SIGNED URL时,一切都可以通过'getObject'操作正常运行,但是在使用'putObject'-operation访问预签名URL时出现以下错误:

<Error>
<Code>SignatureDoesNotMatch</Code>
<Message>
The request signature we calculated does not match the signature you provided. Check your key and signing method.
</Message>
<AWSAccessKeyId>MY ACCESS KEYE</AWSAccessKeyId>
<StringToSign>
AWS4-HMAC-SHA256 20190927T094448Z 20190927/eu-west-1/s3/aws4_request ebdd9a976544557f130250f087dd596219b8e1777f292d1f2e06295df8367aa6
</StringToSign>
<SignatureProvided>
MY SIGNATURE PROVIDED
</SignatureProvided>
<StringToSignBytes>
STRING TO SIGN BYTES
</StringToSignBytes>
<CanonicalRequest>
GET /test.txt Content-Type=text%2Fplain&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=<SHA256CODE>&X-Amz-Credential=<AMZ CREDENTIALS>eu-west-1%2Fs3%2Faws4_request&X-Amz-Date=20190927T094448Z&X-Amz-Expires=120&X-Amz-SignedHeaders=host%3Bx-amz-content-sha256 host:test-host.s3.eu-west-1.amazonaws.com x-amz-content-sha256: host;x-amz-content-sha256 UNSIGNED-PAYLOAD
</CanonicalRequest>
<CanonicalRequestBytes>
CANONICAL REQUEST BYTES
</CanonicalRequestBytes>
<RequestId>REQUEST ID</RequestId>
<HostId>
HOST ID
</HostId>
</Error>

这些是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>

我浏览了StackOverflow上的所有其他相关文章,并修复了他们提到的可能解决方案,例如添加区域,signatureVersion和ACL。但这仍然行不通。

0 个答案:

没有答案