使用 Laravel 从 Web 服务器流式传输 Amazon S3 对象

2023-11-24

在我使用 laravel 5.1 构建的 Web 应用程序中,用户可以上传我存储在 Amazon S3 中的一些敏感文件。后来我想要用户经许可下载此文件。由于我希望进行此身份验证检查,因此我无法使用传统方法通过直接链接到 S3 中的文件来下载文件。

我的做法:

  1. 当用户请求下载时,我的服务器会在本地下载文件,然后流式传输给用户。Issue:需要很长时间,因为有时文件太大。

  2. 为用户提供一个预签名 URL,以便直接从 S3 下载。 URL 的有效期只有 5 分钟。Issue:如果该 URL 被共享,任何人都可以在 5 分钟内下载它。

  3. 根据这篇文章,将数据直接从 S3 流式传输到客户端。这看起来很有希望,但我不知道如何实现。

根据这篇文章,我需要:

  1. 注册流包装器 -这是我的第一个问题,因为我不知道如何掌握S3Clientobject因为laravel使用flysystem,我不知道调用什么方法来获取这个对象。也许我需要在我的composer.json中单独包含S3包?
  2. 禁用输出缓冲 -我需要在 laravel 中执行此操作还是 laravel 已经处理好了?

我确信其他开发人员以前也遇到过这样的问题,并且希望获得一些帮助指示。如果有人已经使用 laravel 直接从 S3 流式传输到客户端Response::download($pathToFile, $name, $headers),那么我很想听听你的方法。


通过评论中的讨论,我得出了一些我想分享的要点。

Pre-Signed URLs

正如@ceejayoz 指出的那样,pre-signedURL 不是一个坏主意,因为:

  1. 我可以将时间保持在 10 秒之内,这对于任何重定向和开始下载来说都是完美的,但不足以共享链接。
  2. 我之前的理解是下载必须在给定的时间内完成。因此,如果链接在 10 秒后过期,则必须在此之前进行下载。但@ceejayoz 指出事实并非如此。允许完成已开始的下载。
  3. With cloud front,我还可以限制IP地址,以增加更多的安全性。


IAM Roles

他还指出了另一个不太好的方法- 创建临时 IAM 用户。如果做得不正确,这将是一场维护噩梦,因此只有在您知道自己在做什么的情况下才可以这样做。


Stream From S3

这是我现在选择的方法。也许稍后我会转向第一种方法。

Warning:如果您进行流式传输,那么您的服务器仍然是中间人,所有数据都将通过您的服务器传输。因此,如果失败或速度缓慢,您的下载就会很慢。

我的第一个问题是 how to register stream wrapper:

由于我使用 Laravel 并且 laravel 使用 Flysystem 进行 S3 管理,因此我没有简单的方法来获取 S3Client。因此我添加了额外的包AWS SDK for Laravel in my composer.json

"aws/aws-sdk-php-laravel" : "~3.0"

然后我写了我的代码如下:

class FileDelivery extends Command implements SelfHandling
{
    private $client;
    private $remoteFile;
    private $bucket;

    public function __construct($remoteFile)
    {
        $this->client = AWS::createClient('s3');
        $this->client->registerStreamWrapper();
        $this->bucket = 'mybucket';
        $this->remoteFile = $remoteFile;
    }

    public function handle()
    {
        try
        {
            // First get the meta-data of the object.
            $headers = $this->client->headObject(array(
                'Bucket' => $this->bucket,
                'Key' => $this->remoteFile
            ));

            $headers = $headers['@metadata'];
            if($headers['statusCode'] !== 200)
            {
                throw new S3Exception();
            }
        }
        catch(S3Exception $e)
        {
            return 404;
        }

        // return appropriate headers before the stream starts.
        http_response_code($headers['statusCode']);
        header("Last-Modified: {$headers['headers']['last-modified']}");
        header("ETag: {$headers['headers']['etag']}");
        header("Content-Type: {$headers['headers']['content-type']}");
        header("Content-Length: {$headers['headers']['content-length']}");
        header("Content-Disposition: attachment; filename=\"{$this->filename}\"");

        // Since file sizes can be too large,
        // buffers can suffer because they cannot store huge amounts of data.
        // Thus we disable buffering before stream starts.
        // We also flush anything pending in buffer.
        if(ob_get_level())
        {
            ob_end_flush();
        }
        flush();

        // Start the stream.
        readfile("s3://{$this->bucket}/{$this->remoteFile}");
    }
}

我的第二个问题是 Do I need to Disable output buffering在拉拉维尔?

恕我直言,答案是肯定的。缓冲使数据立即从缓冲区中刷新,从而降低内存消耗。由于我们没有使用任何 Laravel 函数将数据卸载到客户端,因此这不是由 Laravel 完成的,因此需要我们来完成。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Laravel 从 Web 服务器流式传输 Amazon S3 对象 的相关文章

随机推荐

  • MousePressEvent,QGraphicsView中的位置偏移

    我有一些困难QGraphicsView and QGraphicsScene 当我缩放 取消缩放场景并使用 mousePressEvent 创建项目时 我的位置有一个偏移 如何避免这种情况 event pos 似乎是问题 from PyQt
  • 如何使用 selenium 3.0.0 beta 关闭 geckodriver

    环境 Win 7 Selenium 3 0 0 测试版 FireFox 49 0 1 System setProperty webdriver gecko driver C geckodriver exe WebDriver driver
  • Apache ProxyPass 未加载资源

    我配置了 apache proxypass 它可以工作 但无法加载图像 javascript CSS 等 我想 proxypass 到另一台服务器 而不是本地主机 以下是我的配置 查看错误图像
  • Google 地图 API 的服务帐户

    On the Google 云身份验证概述页面上对云服务进行了以下说明 对于几乎所有情况 无论您是在本地开发还是在外部开发 生产应用程序 您应该使用服务帐户 而不是 用户帐户或 API 密钥 考虑到这一点 我的问题是 当使用 Google
  • 异常处理 ASP.NET MVC Web API

    首先 是的 我们已经创建并正在使用一个继承自 ExceptionFilterAttribute 的异常过滤器 它会在应用程序启动时在我们的身份过滤器之后立即注册到配置中 并且如果我们的 API 内部某个地方发生错误 它的工作效果几乎与预期一
  • 如何处理 Web 驱动程序 Selenium python 浏览器或应用程序可能不安全的问题?

    我正在尝试自动登录 Gmail 但看到此错误 我认为这一定是因为该网站能够检测到自动化并阻止它 大家能告诉我如何克服这个问题吗 我的个人帐户没有发现此问题 但只有普通帐户才会出现此问题 In you account profile in S
  • 在 kableExtra() 中设置字幕格式

    是否可以将字幕格式设置为kableExtra 我想在编织时将表格的标题居中并加粗HTML in RMarkdown 我试图将桌子包裹起来CSS div文本居中的位置 但这并没有产生预期的结果 样本表 library kableExtra k
  • python下载速度极慢

    有没有办法提高Python上的url下载速度 我有一个用 VB6 编写的程序 无需尝试即可使用 Python 我已经转换了这个东西 现在正在尝试 Python linux 中的东西似乎慢得多 时间是原来的两倍 即使是该程序的初始版本似乎也比
  • Flutter 如何改变ListView中鼠标滚轮的滚动速度?

    我是初学者 我正在 Windows 下编写一个关于 Flutter 的应用程序 问题是 ListView 中的文本通过鼠标剪辑滚动得太慢 我尝试覆盖 ScrollPhysics 但没有成功 请提供一种改变滚动速度的工作方法 对于找到这篇文章
  • 通过Java JDBC连接Hive

    这里有一个问题从 java 连接到 Hive但我的是不同的 我的配置单元在 machine1 上运行 我需要使用在 machine2 上运行的 Java 服务器传递一些查询 据我了解 Hive 有一个 JDBC 接口 用于接收远程查询 我从
  • JSX 元素类型没有任何构造或调用签名。打字稿

    In case compose使用时出现错误JSX element type Option does not have any construct or call signatures redux 版本 3 7 2 import as Re
  • 网站图标 - 最佳实践 [关闭]

    Closed 这个问题需要多问focused 目前不接受答案 更新的问题 2022 年创建网站图标时的最佳实践是什么 这是 2013 年提出的原始问题 我正在尝试了解网站图标 触摸图标以及现在的平铺图标所需的所有这些不同尺寸和格式 我读过这
  • 如何在 iOS 7 中恢复 UIButton 边框?

    我建立了一个旧项目Xcode 5 中的 iOS SDK 6 1 然而 当应用程序在运行 iOS 7 的 iPhone 上运行时 UIbutton 是无边框的 我已经检查过 xib是 构建 gt 项目部署目标 5 0 如何配置 Xcode 5
  • 如何从 Azure Blob 存储查看图像而不是下载图像?

    好的 我正在使用 Node js 和 Azure Blob 存储来处理一些文件上传 当一个人上传图像时 我想向他们显示图像的缩略图 上传效果很好 我将其存储在我的 blob 中 我使用了这个很好的链接 使用 Azure SDK for No
  • 未经许可的地理定位[重复]

    这个问题在这里已经有答案了 我注意到现代基于 html5 的地理定位总是询问用户 您想与此网站共享您的位置吗 这很好 但我知道还有其他途径可以尝试确定大致的地理位置 而无需请求此许可 如果我记得的话 这些服务使用 IP 数据库来尝试跟踪地理
  • 我可以将 socket.io 事件侦听器分离到不同的模块中吗?

    我正在处理超过 15 个不同的套接字事件 我想在与这些事件相关的模块中管理某些 socket io 事件 例如 我想让一个名为 login js 的文件处理login套接字事件 名为 register js 的文件处理注册套接字事件 索引
  • 根据 Django 管理中的父模型预填充内联

    我有两个模型 Event and Series 其中每个事件都属于一个系列 大多数时候 一个事件start time与其系列相同default time 这是模型的精简版本 models py class Series models Mod
  • 有哪些好的 WCF/Web 服务安全读物? [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 目前不接受答案 最近 我做了很多与 WCF Web 服务和分布式计算相关的学习和工作 但大多数安全概念都超出了我的理解范围 传输安全 消息安全 加密 证书等 我了解
  • Arraylists 的 Arraylist 的通用类型

    在正常的数组列表初始化中 我们过去定义泛型类型如下 List
  • 使用 Laravel 从 Web 服务器流式传输 Amazon S3 对象

    在我使用 laravel 5 1 构建的 Web 应用程序中 用户可以上传我存储在 Amazon S3 中的一些敏感文件 后来我想要用户经许可下载此文件 由于我希望进行此身份验证检查 因此我无法使用传统方法通过直接链接到 S3 中的文件来下