【问题标题】:Temporary S3 Bucket URL for serving Images用于提供图像的临时 S3 存储桶 URL
【发布时间】:2019-08-27 23:45:54
【问题描述】:

使用“aws/aws-sdk-php”:“^3.0@dev”

我正在创建一个图像共享网站,但不希望人们将我的 URL 复制到另一个网站以窃取我的内容/带宽。

我最初将对象存储为

return $s3->putObject([
        'Bucket' => $bucket,
        'Key'    => $key,
        'Body'   => $file,
        'ACL'    => 'public-read',
    ]);

但我已经删除了“公开阅读”,所以现在下面的 URL 不再有效

 https://mybucket-images.s3.us-west-1.amazonaws.com/' . $key);

我需要做什么来创建一个仍然可以在客户端缓存以访问对象的临时 URL?

我正在考虑的一件事是每周或每月更改一次密钥,但这需要我使用 cronjob 更新所有对象。一定有办法创建临时访问 URL?

【问题讨论】:

  • 谁写入存储桶 - 存储桶权限是什么?如果您是唯一的作者,则不确定问题出在哪里 - 假设您发布的内容不是机密的,并且对随机读者来说没有什么价值。
  • 我的后端将用户上传的图像写入存储桶。所有图片都是公开的,但我想防止人们将我的 S3 URL 复制到另一个站点。
  • 因此,您正在尝试使客户可以访问从您的站点获取的 URL,但如果他们从其他站点读取 URL,则不能访问?
  • 是的,我的网站会生成一个可以持续 30 天左右的 URL,但随后会过期并需要我的网站重新生成它。

标签: php amazon-s3


【解决方案1】:

使用您的服务器为存储桶中的密钥生成预签名 url。

//Creating a presigned request
$s3Client = new Aws\S3\S3Client([
    'profile' => 'default',
    'region'  => 'us-east-2',
    'version' => '2006-03-01',
]);

$cmd = $s3Client->getCommand('GetObject', [
    'Bucket' => 'my-bucket',
    'Key'    => 'testKey'
]);

$request = $s3Client->createPresignedRequest($cmd, '+20 minutes');
$presignedUrl = (string) $request->getUri();

取自https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/s3-presigned-url.html

但是每次您的页面有请求时,您都必须这样做。并且该链接在任何地方都有效。您只需缩短其有效期。

如果您的网站是基于 API 的并且您通过 API 检索网址,这可能与您有关:

  • 如果您的网站有登录功能,您可以在提供预签名的 url 之前检查身份验证逻辑。

  • 如果没有,您可以使用 Http Referrer(可以被欺骗)。或者一个 api 密钥(比如在 API Gateway 中)

【讨论】:

  • 我相信这就是我要找的,谢谢!我认为我会让链接有效期为 7 天。
【解决方案2】:

您可以使用以下代码:

 // initiate connection to your S3 bucket
    $client = new S3Client(['credentials' => ['key' => 's3 key', 'secret' =>'s3 secrete'], 'region' => 's3 region', 'version' => 'latest']);

        $object = $client->getCommand('GetObject', [
            'Bucket' => 's3 bucket',
            'Key' => 'images/image.png' // file
        ]);

        $presignedRequest = $client->createPresignedRequest($object, '+20 minutes');
        $presignedUrl = (string)$presignedRequest->getUri();
        if ($presignedUrl) {
            return $presignedUrl;//presigned URL
        } else {
            throw new FileNotFoundException();
        }

【讨论】:

    【解决方案3】:

    如果您的目的是让您的内容只能通过发布在您网站上的 URL 来阅读 - 而不是让相同的 Web 客户端使用从另一个站点访问的相同 URL 不起作用,我认为您可能会发现这相当困难。想到的大多数方式都是相当可恶的。

    我会看看这个,看看它是否适合你:

    Restricting Access to a Specific HTTP Referrer

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-06-14
      • 1970-01-01
      • 2016-12-22
      • 2021-10-04
      • 2023-03-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多