我想将用户个人资料图片存储在S3存储桶中,但要保持这些图片的私密性。为了做到这一点,我创建了一个预签名的网址,每当图像是必需的。然而,这每次都会创建一个唯一的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,以便用户浏览器可以缓存图像?
6条答案
按热度按时间hmtdttj41#
这是我在看完这篇文章后想到的一个python解决方案。它使用freezegun库来操纵时间,使签名在给定的时间段内保持不变。
hc8w905p2#
也许是一个迟来的回复,但我会添加我的方法,以利于人们阅读这在未来。
为了强制浏览器缓存生效,每次都生成相同的URL是很重要的,直到你特别希望浏览器从服务器重新加载内容。不幸的是,sdk中提供的预签名者依赖于当前的时间戳,每次都会导致一个新的url。
这个例子是用Java编写的,但是它可以很容易地扩展到其他语言。
GetObjectRequest构建器(用于创建预签名的URL)允许覆盖配置。我们可以提供一个自定义签名器来修改它的行为
在这里,我们覆盖签名时钟来模拟一个固定的时间,这最终会导致url中的过期和签名一致,直到未来的某个日期:
更多详情请点击此处:
https://murf.ai/resources/creating-cache-friendly-presigned-s3-urls-using-v4signer-q1bbqgk
vcirk6k63#
与其使用预签名的URL机制,不如向应用程序添加一个经过身份验证的端点,并在该端点内检索图像?在你的
img
标签中使用这个URL。这个端点可以缓存图像,并为浏览器提供适当的响应头来缓存图像。t5fffqht4#
类似于@Aragorn的概念,但这是更完整的代码。这又是Java。此外,由于我的应用程序是多区域的,我不得不把在区域属性。
对于上面注入的
CustomAwsSigner
。关键的区别是我抛出了一个不支持的操作异常。bvjveswy5#
如果有人在使用golang预签名具有缓存可能性的URL时遇到困难,您可以创建一个自定义的签名处理程序,并将命名的处理程序与您自己的交换,以更改签名时间并使时间桶的URL相同:
nnsrf1az6#
将解决方案从弗朗西斯科的解决方案扩展到golang v2,沿着这条线的东西可能会起作用: