一、下载功能其实很好实现,原来直接将文件的地址直接放在a里就可以实现了。但是这样给系统的安全性带来了不少的隐患。怎样隐藏下载文件的真实地址?
有一种办法,其主要思想是:1.以二进制数据流方式打开欲下载文件。2.按二进制数据流读取,并输出3.输出的内容强制浏览器打开一个下载框,以便下载。
打开一个文件可以用fopen()方法,文件的路径在此方法中以参数的方式传入,这样便实现了隐藏文件真实路径的目的,而不是简单的用a将文件绝对路径暴露。下面是我写的一个简单的下载类:(重要部分已添加说明)
<?
class downLoad {
function downLoading($fileUrl,$fileName){
//判断文件是否存在
if($this->fileExists($fileUrl,$fileName)==false){
exit();
}
//获得文件大小
$fileSize = filesize($fileUrl.$fileName);
//已二进制方式打开文件
$objDownload = fopen($fileUrl.$fileName,"rb");
//发送header
header("Content-type:application/octet-stream");//设置文件类型为二进制数据流
header("Content-length:$fileSize");//文件大小
header("Content-Disposition: attachment;filename=$fileName");//提供推荐的文件名来强制浏览器弹出一个保存文件对话框。
fpassthru($objDownload);
}
function fileExists($fileUrl,$fileName){
$what = file_exists($fileUrl.$fileName);
return $what;
}
}
?>二、虽然实现了文件路径的隐藏,但是还是感到不是十分的安全。
功能1、当该文件需注册后才能下载
session_start();
if(!isset($_SESSION["loginname"])){
echo "对不起,你无权下载!";
exit();
}else{
$do = new downLoad();
$do->downLoading("../download/file",$_GET["filename"]);
}功能2.每个用户有自己的下载文件,其他用户不能下载。
功能1可以简单的过滤下载用户,但是只要存在session在url中输入其他文件地址就可以下载其他用户的任意文件了,不好。
失败案例1:我试着禁掉用户在url中输入下载地址:(http_referer为链接到该页的前一页地址,server_name为当前运行脚本所在服务器主机的名称。当前一页中以a链接至此页时http_referer有值,而当使用页面刷新、header、javascript时http_referer不存在!这三种方式在IE中不会视为事件使http_referer产生值!)
$serverName = $_SERVER['SERVER_NAME'];
$httpReferer = $_SERVER['HTTP_REFERER'];
$requestArray = explode("/",$httpReferer);
$requestSN = $requestArray[2];
if($httpReferer==""||$requestSN!=$serverName){
echo "非法链接!";
exit();
}这样只有在用户在本站中有<a href=""></a>链接时才能下载该文件,其他网站的盗用或着url直接输入不会下载该文件。(假设本站不会提供其他用户资源的a链接,只提供该用户自己的资源链接地址)用户在想要非法下载其他用户的资源时,一般会在url中输入地址,这样貌似解决了功能2的需求,但是当使用迅雷工具下载时,在其提供的url输入地址却任然可以下载其他用户资源,这是因为,当以迅雷下载时,可以看做触发了a时间http_referer不为空!
2.其他思想:
想用户下载资源似有化貌似只能使该用户id对应自己相应的资源。
方法1.存储一个用户下载列表。当下载时比对。
方法2.使用标志位来命名资源。当下载是判断。
方法3.使用linux中的权限控制。(未实现)
以上纯属个人看法,忘大虾务笑。下载安全问题一直是块心病,倘若有更好的方法,还忘高人指教。小弟谢过。
3540

被折叠的 条评论
为什么被折叠?



