【问题标题】:Amazon S3 force MP3 file download bypassing web serverAmazon S3 强制 MP3 文件下载绕过 Web 服务器
【发布时间】:2013-07-18 04:30:38
【问题描述】:

我一直在尝试寻找一种方法来强制从 Amazon S3 下载 MP3 文件,但我发现的所有实现都会通过 Web 服务器示例传递文件:

S3 --> 我的 Web 服务器 --> 客户端。

我如何链接到 Amazon S3 上的文件,这将强制从 Amazon s3 直接下载,而无需通过我的网络服务器?

【问题讨论】:

  • 类似但不重复..这是关于不通过网络服务器传递文件的具体强制下载

标签: php amazon-s3 download


【解决方案1】:

你的答案是 HTML 5

<a href="$download_link" download="$file_name">Click Me</a>

这会强制浏览器像“保存”一样保存文件

【讨论】:

  • 这不是一个坏主意。我不知道那存在。对于不支持 HTML 5 的浏览器是否有解决方法?
【解决方案2】:

您需要设置 S3 对象的这些元数据:

Content-Type: "application/octet-stream"
Content-Disposition: "attachment"

有时只设置Content-Disposition 就足够了。 您也可以从 S3 控制台或通过 AWS Api 执行此操作。

【讨论】:

    【解决方案3】:

    您可以直接引用您上传到 Amazon S3 存储桶的任何对象,就好像它本身就是一个 Web 服务器一样。

    例如,如果您的存储桶名称为 xyz100,并且您上传了一个名为 music.mp3 的 mp3,您可以使用以下链接格式直接从 S3 下载它:

    https://s3.amazonaws.com/xyz100/music.mp3

    您知道您可以通过基于 Web 的 Amazon Web Services 控制台或使用任何免费软件工具将对象/文件上传到 S3。

    当对象上传到 S3 时,您可以为对象指定 ACL 或安全策略。默认情况下,对象是私有的,如果您尝试如上所示访问该文件,您将收到拒绝访问错误消息。

    解决此问题的第一种方法是将对象公开,这样就无需在 url 本身中使用任何特殊签名。但是,如果您认为文件可能会被高带宽下载滥用,或在其他人的网站上进行深度链接,则将对象公开可能会带来风险。

    第二种方法是将对象保留为私有,并创建一个包含签名的直接 url。这需要更多技巧,但有一些 PHP 工具包可以轻松地为您创建签名链接,包括亚马逊自己提供的工具包。否则,Amazon S3 Web 控制台允许您创建签名链接。

    关于签名链接最重要的一点是,您可以指定链接到期的时间。这可以成为救命稻草,因为您可以即时创建链接,例如,链接将在 30 分钟后过期。这有助于防止滥用和深度链接,但当然是公开使用私有 S3 对象的最复杂方式,当然还需要服务器。

    虽然技术上可以让某种类型的客户端 JavaScript 为您签署链接,但客户端代码需要包含您的访问密钥和秘密密钥,这将是一个主要的安全漏洞,无论您如何混淆它。规则 #1,永远不要创造任何进入野外的物品,包括你的亚马逊钥匙,无论它们多么混乱。

    如果上述对象的直接 url 是私有的并且需要签名,那么这里将是一个示例:

    https://s3.amazonaws.com/xyz100/music.mp3?Expires=1687832834&Signature=GTje51Mo47BfkGqS1gO0Ns%2FrHUk%3D

    您不需要通过您的 Web 服务器传递对象的实际数据,您可以使用上面详述的方法向任何用户发出到 S3 的直接链接。请注意确保在上传时正确设置 Content-Type,大多数工具会自动执行此操作。如果设置不正确,文件将无法正确打开。这是控制例如图片是否被下载和保存(不正确的 Content-Type 或默认二进制类型),或者只是在浏览器中显示(正确的 Content-Type)。

    祝你好运,希望这会有所帮助。

    【讨论】:

      【解决方案4】:

      将文件公开,您不需要任何类型的 AWS 客户端库来访问它。您可以使用您选择的文件检索机制来获取文件。

      您需要更改 Content-Type。在 S3 控制台中,右键单击对象并选择属性,然后它位于元数据下。您也可以通过编程方式进行:http://docs.amazonwebservices.com/AWSSDKforPHP/latest/index.html#m=AmazonS3/change_content_type

      <?php
      $file = $_GET['file'];
      header ("Content-type: octet/stream");
      header ("Content-disposition: attachment; filename=".$file.";");
      header("Content-Length: ".filesize($file));
      readfile($file);
      exit;
      ?>
      

      【讨论】:

      • 不会 readfile() 通过服务器传递文件吗?我正在尝试将其直接发送给客户
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-02-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-25
      • 2011-09-07
      • 2013-06-08
      相关资源
      最近更新 更多