我有一个用于播放和下载mp3文件的codeigniter项目。用户和管理员可以从前端和后端播放mp3文件,但用户只能使用下载助手从下载控制器中下载这些文件。到目前为止,我就是这样做的,我在声音目录中添加了htaccess文件以防止直接下载,并且该文件可以运行,但是这完全阻止了用户播放mp3文件。
<FilesMatch "\.(mp3)$">
Order allow,deny
Deny from all
</FilesMatch>
并且下载控制器可以正常工作,以允许特定用户下载这些文件。如何编辑它以允许在该目录中播放mp3文件而无需直接访问完整下载路径?
我想从特定页面访问mp3文件以播放和下载它,并拒绝对其进行任何其他直接访问。
请不要让项目中的音频元素使用mp3文件的绝对路径来播放它。我什至尝试使用相对路径,但也没有玩
答案 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以外的任何方式,我们希望避免客户端手动转到该路由并获取令牌