如何通过签名URL在S3对象上定义Cache-Control标头?

时间:2017-04-20 16:49:31

标签: javascript amazon-s3

按照this guide中的说明操作,我设法通过签名网址上传。它看起来像这样:

const s3 = new aws.S3();

const s3Params = {
  Bucket: S3_BUCKET,
  Key: fileName,
  Expires: 60,
  ContentType: fileType,
  ACL: 'public-read',
  CacheControl: 'public, max-age=31536000',
};

s3.getSignedUrl('putObject', s3Params, (err, data) => {
  // ...
});

...除了我的CacheControl param(我自己添加;它不在指南中)似乎没有生效。当我使用上面的代码生成签名的URL并向其上传内容时,S3中的结果对象没有Cache-Control标题。

我做错了什么?

2 个答案:

答案 0 :(得分:9)

无论您在签名网址生成期间设置了什么,都必须在上传请求中发送Cache-Control标头。

这是一个错误还是一个故意的行为是值得怀疑的,超出了我的回答能力。正如您所注意到的,Cache-Control标题是签名URL的一部分,但无论出于何种原因,在文件上载期间信息都被完全忽略,即。未在CacheControl函数中指定getSignedUrl()属性仍允许客户端将Cache-Control标头设置为他们选择的任何值。

如果您需要控制Cache-Control标题,那么使用getSignedUrl()很可能不适合您的用例。

解决方案

AWS现在支持一种名为AWS Signature version 4的新签名方案,该方案允许完全控制上传请求可能包含或不包含的内容,包括发送哪些标题以及具有什么值。< / p>

JavaScript SDK支持这个新的签名版本:createPresignedPost()

有关如何生成此预签名POST政策以及上传表单应如何显示的详细示例,请直接在AWS's documentation上找到。

尽管该示例演示了通过标准http upload <form>元素上传文件,但原则可以应用于任何能够执行HTTP通信的客户端/消费者。

实施例

为了完整起见,以下是预签名POST政策的示例(以上链接的AWS文档页面)示例:

{ "expiration": "2015-12-30T12:00:00.000Z",
  "conditions": [
    {"bucket": "sigv4examplebucket"},
    ["starts-with", "$key", "user/user1/"],
    {"acl": "public-read"},
    {"success_action_redirect": "http://sigv4examplebucket.s3.amazonaws.com/successful_upload.html"},
    ["starts-with", "$Content-Type", "image/"],
    {"x-amz-meta-uuid": "14365123651274"},
    {"x-amz-server-side-encryption": "AES256"},
    ["starts-with", "$x-amz-meta-tag", ""],

    {"x-amz-credential": "AKIAIOSFODNN7EXAMPLE/20151229/us-east-1/s3/aws4_request"},
    {"x-amz-algorithm": "AWS4-HMAC-SHA256"},
    {"x-amz-date": "20151229T000000Z" }
  ]
}

此POST策略在请求中设置以下条件:

  • 上传时间必须在2015年12月30日午夜UTC之前。
  • 内容只能上传到sigv4examplebucket。存储桶必须位于您在凭据范围(x-amz-credential表单参数)中指定的区域中,因为您提供的签名仅在此范围内有效。
  • 您可以提供以user/user1开头的任何密钥名称。例如,user/user1/MyPhoto.jpg
  • ACL必须设置为public-read
  • 如果上传成功,则用户的浏览器会重定向到http://sigv4examplebucket.s3.amazonaws.com/successful_upload.html
  • 对象必须是图像文件。
  • x-amz-meta-uuid代码必须设为14365123651274
  • x-amz-meta-tag可以包含任何值。

请注意,此示例中的条件列表并非详尽无遗且支持CacheControl 。请参阅creating a POST policy文档,了解如何使用此功能。

答案 1 :(得分:0)

与接受的答案相反,您可以将 Cache-Control 添加到从 getSignedURL 获得的 URL,但仅限于 getObject 操作。我希望这能帮助那些为了 getObject 来到这里的人。

这就是我所做的

    const params = {
      Bucket: <YOUR_S3_BUCKET>,
      Key: <YOUR_KEY>,
      ResponseCacheControl: `public, max-age=900, immutable`,
      Expires: 900 // default value
    }

    return this.S3.getSignedUrl('getObject', params)

生成的 URL 如下所示

https://<YOUR_S3_BUCKET>.s3.us-east-2.amazonaws.com/<YOUR_KEY>?...&response-cache-control=public%2C%20max-age%3D900%2C%20immutable

和响应头 Cache-Control: public, max-age=900, immutable

查看文档 here 并注意最后一个示例中的参数。您可以在那里找到 ResponseCacheControlExpires 参数。

如果您查看文档,您会看到 putObject 包含 CacheControl 参数,但将其添加到 params 并没有任何作用。