gpt4 book ai didi

PHP 阻止直接访问文件但只允许登录文件的所有者

转载 作者:行者123 更新时间:2023-11-29 00:15:21 25 4
gpt4 key购买 nike

已编辑:downl.php

嗨皇家 Bg。

不知该如何感谢。但是你的代码看起来不错,但对我来说很难
理解所以我仍然引用传递到下载页面....我的 downl.php 页面如下所示:

 require('staff.php'); // User controll


if(($thisuser->getGroupId() != 4)){
header('Location: index.php');
require('index.php');
exit;
}

//从 rum_st.php 接收学生文件 id、学生 id 和 rums id(类(class) id)

if (isset($_GET['f-id']) && is_numeric($_GET['f-id']) && 
$_GET['f-id'] >= 1 && isset($_GET['s-id']) && is_numeric($_GET['s-id']) &&
$_GET['s-id'] >= 1 && isset($_GET['r-id']) && is_numeric($_GET['r-id']) && $_GET['r-id'] >= 1 ) {


$file_id_s = $_GET['f-id'];
$stud_id = $_GET['s-id'];
$rums_id = $_GET['r-id'];



$sql = " SELECT t.ticket_id, t.ticketID, t.staff_id, t.subject, r.rums_id, r.staff_id, r.rumsname ".
" f.file1_id, f.rums_id, f.ticket_id, f.file_name, f.staff_id, f.filetype, f.filesize, f.created, f.dept_id ". // dept_id means class_id or grade_id
" sc.school_id, sc.school_name ".
" FROM ice_cust_ticket t ".
" INNER JOIN ice_file f ON f.ticket_id = t.ticket_id ".

" INNER JOIN ice_rums r ON r.rums_id = f.rums_id ".
" INNER JOIN ice_cust_school sc ON sc.school_id = f.dept_id ". // school means class or grade

" WHERE f.rums_id = ".$rums_id." " .
" ORDER by f.created ";


$res = mysql_query($sql);


while ($row = mysql_fetch_array($res)) {

$filename = htmlspecialchars($row['file_name']);
$fileID = $row['file1_id'];
$rums_id3 = $row['rums_id'];
$dept_id = $row['dept_id']; // Class id if he/she is from class 4 .. 5 ..
$dept_id3 = explode(',', $dept_id);

if(in_array($thisuser->getdeptID(), $dept_id3)){


$rumsname = htmlentities($row['rumsname'], ENT_QUOTES, "UTF-8");
$file_name = htmlentities($row['file_name'], ENT_QUOTES, "UTF-8");
$teacher_id = $row['staff_id'];

// Teacher file
// $target_path = "rums/".$teacher_id."/".$rumsname."/".$file_name."/";

// Student file
$target_path_st = "rums/".$teacher_id."/".$rumsname."/".$file_name."/".$thisuser->getId()."/";



$sql_st_file = " SELECT * FROM ice_student_file WHERE file_id = ".$fileID." AND stud_id = ".$thisuser->getId()." ";
$res_st = mysql_query($sql_st_file);
$row_st = mysql_fetch_array($res_st);
$file = $row_st['file_name'];
$result = $row_st['result'];
$opinion = $row_st['opinion'];


// with link like target=_blank......
//$url = '<a href="'.$target_path_st.$file.'" target="_blank id="attached-file-link" style="text-decoration:none;">'.$file.'</a>';

// or without link
$url = '<a href="'.$target_path_st.$file.'">'.$file.'</a>';

// this give me the same problem.. shows the link where it is and I have to click to download
//echo $url;

// echo '<META HTTP-EQUIV=Refresh CONTENT="0; URL='.$url.'">'; // And This give me Error 403

// The question is where to put the headers and what to write on headers...


}

}

}


我正在用 PHP 为我的学校创建一个简单的系统。教师在名为 rums 的文件夹中创建自己的类(class)他们可以将这些类(class)授予不同类(class)的访问权限。例如,Linda 老师创建了名为 Biology 的类(class),并授予了 4 类和 5 类的访问权限。效果很好。

所以这将是 localhost\my\my2\rums\...并在这里创建名为 Biology 的文件夹。但是在 Biology 之前,它也用她的用户 ID nr 创建了一个文件夹,例如 Linda 用户 ID 是 91,只是为了防止与其他老师的类(class)名称发生冲突。所以它会像下面这样:localhost\my\my2\rums\91\Biology

Linda 将可下载文件(如 docx 和 pdf 文件)插入此 Biology 文件夹中,4 年级和 5 年级的学生可以下载。然后他们可以将不同的文件插入到这个文件夹中,作为对家庭作业的回应,这样她也可以下载学生的文件。到这个php页面只能访问那些有权限的类。它工作正常,他们可以看到教师文件。

因此,如果学生我们说她的名字是来自第 4 类的 Sarah 将文件插入到此文件夹中,他将只能看到她自己插入的文件..并且它工作正常。没有其他人可以看到它。从数据库中我得到那些文件:

    $target_path_teacher_file = "rums/".$teacher_id."/".$rumsname."/".$file_name."/";
$target_path_student_file = "rums/".$teacher_id."/".$rumsname."/".$file_name."/".$thisuser->getId

()."/";

为了在表格上显示,我将它们打印成这样:

<td><center><?php print '<a href="'.$ target_path_teacher_file.$filename.'" target="_blank id="attached-file-link" style="text-decoration:none;">'.$filename.'</a>'; ?></center></td>
<td><center><?php print '<a href="'.$target_path_student_file.$file.'" target="_blank id="attached-file-link" style="text-decoration:none;">'.$file.'</a>'; ?></center></td>



但是将鼠标悬停在文件上,您可以看到文件所在的空洞链接……如果 David 复制此链接并发送给其他人并在网络浏览器上粘贴,那么即使他们也可以下载他的文件和教师文件。

所以我亲爱的人..我的问题是如何防止除莎拉以外的其他注册和未注册人员下载?我尝试使用 .htaccess 文件但没有成功。

您能提供的任何帮助将不胜感激。
/乔纳斯

enter image description here

最佳答案

乍一看,我可以想象的解决方案是将文件存储到非公共(public)目录中,无需复杂的目录权限:

即:

www/private/assignment.docx

当您验证用户凭据时,即 Sarah 来自第 4 类并且有人请求该文件,在后台运行一个脚本,将文件的临时副本复制到具有不同名称的公共(public)目录即

www/public/sarah-homework-2014-04-20.docx

和/或也不让他们有机会知道文件的来源。或者至少让它变得更难。您不需要直接链接到它。让您的链接指向 download.php,并通过 session user_idfile_id 发送。

如果此 user_id 具有权限,则在 download.php 中验证并直接从 download.php 开始下载


您也可以不允许下载,但将文件与电子邮件一起发送给他们。成功验证用户来自允许的类别后,可以收到带有附件的电子邮件。


我能想到的所有其他方式是文件系统权限、.htaccess 等等。


关于评论中的问题。

我建议通过设置正确的内容类型 header 来使用下载。将文件作为资源打开,并强制下载。

一个简单的用户类,你有userId,所以你可以检查权限(我不会在这里检查权限,这只是一个例子)

class User {
private $_id;
public function setId($id) { $this->_id = $id; }
public function getId() { return $this->_id; }
}

一个简单的类,在收到 file_id 后获取文件信息;

class File {

private $_directory;
private $_filename;
private $_id;

public function setId($file_id) {
$this->_id = $file_id;
$this->getFileInfo();
return $this;
}

private function getFileInfo() {
$result = $this->getDb()->query("SELECT directory, filename FROM files WHERE id = {$this->getId()};");
$row = $this->getDb()->fetch($result);
$this->_directory = $row['directory'];
$this->_filename = $row['filename'];
}

public function getDirectory() { return $this->_directory; }
public function getFileName() { return $this->_filename; }
public function getId() { return $this->_id; }

}

然后是下载类。下载类接收 $user 和 $file 的实例。设置属性file_id和user_id后,用这些实例调用下载类

class Download {

private $_path;

/**
* @var File
*/
private $_file;
/**
* @var User
*/
private $_user;
/**
* @var Download
*/
private $_size, $_info, $_ext, $_handle;
private static $_inst = null;

/**
*
* @param User $user
* @param File $file
* @return Download
*/
public static function init(User $user, File $file) {
if (self::$_inst == null) {
self::$_inst = new self();
self::$_inst->_file = $file;
self::$_inst->_user = $user;
self::$_inst->setPath();
}
return self::$_inst;
}
/**
* @return File
*/
public function getFile() { return $this->_file; }
/**
* @return User
*/
public function getUser() { return $this->_user; }

private function setPath() {
$this->_path = $this->getFile()->getDirectory() . DIRECTORY_SEPARATOR . $this->getFile()->getFileName();
}

public function getPath() { return __DIR__.DIRECTORY_SEPARATOR.$this->_path; }

private function setFileInfo() {
$this->_handle = fopen($this->getPath(), 'r');
$this->_size = filesize($this->getPath());
$this->_info = pathinfo($this->getPath());
$this->_ext = strtolower($this->_info['extension']);

}

private function setHeaders() {
switch ($this->_ext) {
case '.docx':
header("Content-type: application/vnd.openxmlformats-officedocument.wordprocessingml.document");
header("Content-Disposition: attachment; filename=\"".$this->_info['basename']."\"");
break;
case '.doc':
header("Content-type: application/msword");
header("Content-Disposition: attachment; filename=\"".$this->_info['basename']."\"");
break;
case '.txt':
header("Content-Type:text/plain");
header("Content-Disposition: attachment; filename=\"".$this->_info['basename']."\"");
break;
default;
header("Content-type: application/octet-stream");
header("Content-Disposition: filename=\"".$this->_info['basename']."\"");
}
header("Content-length: $this->_size");
header("Cache-control: private");
}

public function forceDownload() {
$this->setFileInfo();
$this->setHeaders();
while(!feof($this->_handle)) {
fread($this->_handle, 2048);
}
fclose($this->_handle);
return true;
}

}

那么你需要类似的东西

$user = new User();
$file = new File;

$user->setId(8);
$file->setId(3);
Download::init($user, $file)->forceDownload();

你也可以不回显文件的基本名称,而是其他的东西,所以你也不会透露它的名字

关于PHP 阻止直接访问文件但只允许登录文件的所有者,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23175058/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com