允许在网站上播放mp3文件,但禁止从直接链接下载

时间:2019-05-29 22:22:14

标签: php .htaccess codeigniter

我有一个用于播放和下载mp3文件的codeigniter项目。用户和管理员可以从前端和后端播放mp3文件,但用户只能使用下载助手从下载控制器中下载这些文件。到目前为止,我就是这样做的,我在声音目录中添加了htaccess文件以防止直接下载,并且该文件可以运行,但是这完全阻止了用户播放mp3文件。

<FilesMatch "\.(mp3)$">
Order allow,deny
Deny from all
</FilesMatch>

并且下载控制器可以正常工作,以允许特定用户下载这些文件。如何编辑它以允许在该目录中播放mp3文件而无需直接访问完整下载路径?

我想从特定页面访问mp3文件以播放和下载它,并拒绝对其进行任何其他直接访问。

请不要让项目中的音频元素使用mp3文件的绝对路径来播放它。我什至尝试使用相对路径,但也没有玩

1 个答案:

答案 0 :(得分:0)

这是个主意

使用PHP文件作为MP3 ...

我知道这听起来很奇怪,但是从技术上讲,PHP文件可以解释为任何文件类型

您的前端:

<audio controls>
  <source src="music.php?token=as5df65s1df" type="audio/mpeg">
</audio>

让我解释一下: 当用户访问页面时,设置只能使用一次的访问令牌,在src上进行设置,并在会话中进行设置

$_SESSION['securePlay'] = 'as5df65s1df';
if(!isset($_GET['token'])){
  //No token? They tried to view the file
  die('access denied');
}


if($_GET['token'] == $_SESSION['securePlay']){
// The one time token hasn't been used yet
// Go ahead and mimic an MP3 and play the music

  $file = 'realMusic.mp3';

  if (file_exists($file)) {
    header('Content-Description: File Transfer');
    header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename='.basename($file));
    header('Content-Transfer-Encoding: binary');
    header('Expires: 0');
    header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
    header('Pragma: public');
    header('Content-Length: ' . filesize($file));
    ob_clean();
    flush();
    readfile($file);
    exit;
  }

  //Here is where you'll want to invalidate the current token and get a new one

} else {
  //The tokens don't match meaning you got a new one and the old one cant be used anymore
  die('access denied');
}


这将执行以下操作: 当用户访问页面时,点击播放即可,因为使用了令牌 用户访问音频src页面时,未设置获取令牌,访问被拒绝 当用户访问音频src页面时,get已在初始加载时加载,因此已过期 如果有人使用inspect查看src文件,然后他们右键单击并保存源,则该令牌已被使用,访问被拒绝

这不是防弹系统,但对普通网站来说却是不错的选择

如果播放有效,则php文件将显示为mp3文件 如果不是有效的播放,它将显示为php文件,并且访问被拒绝

您还需要将mp3文件放在公用文件夹之外,以便只有php文件阅读器才能访问它们。客户端永远不会看到.mp3文件,如果您确实决定将mp3文件放到公共视图中,他们将不得不猜测查看该文件的路径。

我的建议是使用JS音频api,每次要播放歌曲时,创建一个新的音频对象并通过AJAX获得新令牌

注意:在获取新令牌时,请使用POST或除get以外的任何方式,我们希望避免客户端手动转到该路由并获取令牌