当我尝试使用本地服务器上的php流式播放音乐时,我遇到了一个非常奇怪的问题。我有基本的用户名/密码授权检查,以确保用户具有流式传输文件的正确权限。问题在于这些检查。
如果用户没有查看文件的权限,我使用php的exit函数中止脚本,并使用echo来通知用户。退出功能似乎打破了流式传输,即使它没有执行。
以下是我的代码的重点:
function hasPermission($user,$perm)
{
if (!accountHasPermission($user,$perm) )
{
echo "<center><a style='color:indianred'>Failed to Authenticate: 1";
echo "<br><br><a href='javascript:history.back()'>Go Back</a>";
exit;
}
}
function streamTest()
{
$filename = "uploads/path_to_file";
if(file_exists($filename)){
header('Content-type: audio/mpeg');
header('Content-Disposition: filename=' . basename($filename) );
header('X-Pad: avoid browser bug');
header('Cache-Control: no-cache');
readfile( $filename );
}else{
header("HTTP/1.0 404 Not Found");
}
}
hasPermission($_POST["username"],"manageFilesWeb");
streamTest();
exit;
如果我在hasPermission函数中注释掉退出调用,音频将流没有问题。使用chrome,我得到一个好看的音频播放器,看起来像this。当然,退出函数永远不会被调用,因为我使用的是具有正确权限的帐户。我对这一点100%肯定。如果退出功能未被注释掉,则音乐文件将不会在chrome上流式传输,音频播放器将显示为this。我尝试过多个Chrome浏览器并始终获得相同的结果。但是,音乐将在Firefox浏览器中流式传输,无论退出行是否被注释掉。
我尝试过各种其他选项,比如使用return,die,if / else,但是一切都会给我相同的结果。
我还应该注意,我一直在使用hasPermission函数来处理我服务器上的其他所有内容,例如上传和下载文件。直到现在它从来没有给我任何问题。我花了几个小时的试验和错误才发现退出电话可能是问题所在。
我已经到了我不知道发生了什么的地步。我已经不得不删除简单的if / else检查,因为它们正在中断流式传输过程,但是如果我再删除它,我已经达到了显着降低安全性的程度。
更新:我发现了这个问题。授权检查是问题所在。我想在文件传输过程中,_POST数据是未定义的,导致我的授权检查失败。有没有办法在文件流式传输时获取用户名和密码以避免这种情况?
答案 0 :(得分:0)
对于这些经过身份验证的文件服务,使用运行php应用程序的受尊敬的Web服务器的sendfile
方法,表示有两个流行的Web服务器,
<强> 1。 Apache的强>
对于Apache启用xsendfile mod
这里首先阅读用户名&amp;密码使用单独的login.php
// login.php
// session_start & stop life cycle codes
username = $_POST["username"];
password = $_POST["password"];
if(hasPermission(username, password){
$_SESSION["logined"] = true; // setting a session value for successful authentication
}
// login success
然后为流文件添加文件php文件,比如file.php
//file.php
if(isset($_SESSION["logined"])){
$filename = "uploads/path_to_file"; // absolute path to file
header('Content-type: audio/mpeg');
header('Content-Disposition: filename=' . basename($filename) );
header('X-Pad: avoid browser bug');
header('Cache-Control: no-cache');
header('X-Sendfile', $filename);
}else{
header("HTTP/1.0 404 Not Found"); // or 401 Unauthorized
}
<强> 2。 Nginx
对于nginx服务器使用,请按照apache部分中描述的步骤进行操作,只需将X-Sendfile
替换为X-Accel-Redirect
,查看here以获取有关nginx xsendfile的更多说明。