AWS S3 预签名请求缓存

eze*_*ero 10 php caching amazon-s3 amazon-web-services aws-sdk

我想将用户个人资料图片存储在 S3 存储桶中,但将这些图像保密。为了做到这一点,每当需要图像时,我都会创建一个预签名的 URL。然而,这每次都会创建一个唯一的 url,这意味着浏览器永远不会缓存图像,并且我最终会在 GET 请求中支付更多费用。

这是我生成 url 的代码示例,我使用 Laravel:

$s3 = \Storage::disk('s3');
$client = $s3->getDriver()->getAdapter()->getClient();
$expiry = new \DateTime('2017-07-25');

$command = $client->getCommand('GetObject', [
    'Bucket' => \Config::get('filesystems.disks.s3.bucket'),
    'Key'    => $key
]);

$request = $client->createPresignedRequest($command, $expiry);

return (string) $request->getUri();
Run Code Online (Sandbox Code Playgroud)

我认为通过指定日期时间而不是时间单位,它会创建相同的网址,但实际上会在网址中添加剩余的秒数,下面是一个示例:

xxxx.s3.eu-west-2.amazonaws.com/profile-pics/92323.png?X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AXXXXXXXXXX% 2Feu-west-2%2Fs3%2Faws4_request&X-Amz-Date=20170720T112123Z&X-Amz-SignedHeaders=主机&X-Amz-Expires=391117&X-Amz-Signature=XXXXXXXXX

是否可以生成可重复的预签名请求 URL,以便用户浏览器可以缓存图像?

mon*_*kut 7

这是我在关注这篇文章后想出的 python 解决方案。它使用freezegun库来操纵时间,使签名在给定时间内相同。

import time
import datetime

import boto3
from freezegun import freezetime


S3_CLIENT = boto3.client("s3")

SEVEN_DAYS_IN_SECONDS = 604800
MAX_EXPIRES_SECONDS = SEVEN_DAYS_IN_SECONDS



def get_presigned_get_url(bucket: str, key: str, expires_in_seconds: int = MAX_EXPIRES_SECONDS) -> str:
        current_timestamp = int(time.time())
        truncated_timestamp = current_timestamp - (current_timestamp % expires_in_seconds)
        with freeze_time(datetime.datetime.fromtimestamp(truncated_timestamp)):
            presigned_url = S3_CLIENT.generate_presigned_url(
                ClientMethod="get_object",
                Params={
                    "Bucket": bucket,
                    "Key": key,
                    "ResponseCacheControl": f"private, max-age={expires_in_seconds}, immutable",
                },
                ExpiresIn=expires_in_seconds,
                HttpMethod="GET",
            )
        return presigned_url
Run Code Online (Sandbox Code Playgroud)


小智 0

也许您可以将经过身份验证的端点添加到您的应用程序中,并在该端点内检索图像,而不是使用预签名的 URL 机制?img在您的标签等中使用此 URL 。该端点可以缓存图像并为浏览器提供适当的响应标头来缓存图像。

  • 谢谢,这是我的第一个想法,但后来我失去了完全绕过我的服务器获取资产的好处。 (12认同)