php - AWS S3 预签名请求缓存

标签 php amazon-web-services caching amazon-s3 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();

我认为通过指定日期时间而不是时间单位,它会创建相同的 url,但它实际上将剩余的秒数添加到 url,这是一个示例:

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=AXXXXXXXXXXX%2Feu-west-2%2Fs3%2Faws4_request&X-Amz-Date=20170720T112123Z&X-Amz-SignedHeaders=host&X-Amz-Expires=391117&X-Amz-Signature=XXXXXXXXX

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

最佳答案

这是我在关注这篇文章后想出的 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

关于php - AWS S3 预签名请求缓存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45213553/

相关文章:

php - 在 MySQL 数据库中存储路径/层次结构的最佳方式是什么?

php博客分页排名

java - 创建表单来更改永久变量

ios - 如何在没有 Cognito 的情况下授权 dynamoDB?

apache - 为什么 Internet Explorer 缓存过期的 SSL 证书(我可以对此做些什么)?

php - APC 将数据存储在哪里?

ios在页面更改时暂停音频

php - 如何将 RLIKE 与 Doctrine 2 一起使用?

javascript - 完成 AWS 身份验证流程

maven - mvn 部署到 AWS(通过 distributionManagement ssh)