Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 防止在URL中直接访问PDF文档_Php_File_.htaccess_Pdf_Copy Protection - Fatal编程技术网

Php 防止在URL中直接访问PDF文档

Php 防止在URL中直接访问PDF文档,php,file,.htaccess,pdf,copy-protection,Php,File,.htaccess,Pdf,Copy Protection,我想保护pdf文件不被直接链接,而是让我的登录用户能够访问它。我有一个链接,当前指向发布表单的javascript函数: $('nameofdoc').setProperty('value',doc); document.getElementById('sendme').submit() 其中sendme是表单的名称,而doc的名称是我要显示的文档的索引 然后转到一个php文件: $docpath = $holdingArray[0].$holdingArray[1]; $file = $

我想保护pdf文件不被直接链接,而是让我的登录用户能够访问它。我有一个链接,当前指向发布表单的javascript函数: $('nameofdoc').setProperty('value',doc); document.getElementById('sendme').submit()

其中sendme是表单的名称,而doc的名称是我要显示的文档的索引

然后转到一个php文件:

 $docpath = $holdingArray[0].$holdingArray[1];

 $file = $holdingArray[0]; //file name
 $filename = $holdingArray[1]; //path to the file]
 header( 'Location:'.$docpath ) ;
 header('Content-type: application/pdf');
 header('Content-Disposition: attachment; filename="'.$filename  . '"');
 readfile($filename)
这一切都很好,它加载文件并输出pdf。我不能做的是保护目录不被直接链接-即www.mydomain.com/pathToPdf/pdfname.pdf

我曾想过使用.htaccess来保护目录,但它位于共享主机上,因此我不确定其安全性,无论如何,当我尝试时,我无法让它工作

任何帮助都将是巨大的,因为这是我第四天试图解决这个问题

谢谢

更新

我得到了很多帮助,谢谢你,但我还没有完全做到

我有一个.htaccess文件,当从目录请求pdf时,它会启动另一个php文件:

 RewriteEngine on
 RewriteRule ^(.*).(pdf)$ fileopen.php
当fileopen.php文件启动时,它无法打开pdf文件

 $path = $_SERVER['REQUEST_URI'];
 $paths = explode('/', $path);
 $lastIndex = count($paths) - 1;
 $fileName = $paths[$lastIndex]; 

 $file = basename($path);

 $filepath = $path;

 if (file_exists($file)) {
     header( 'Location: http://www.mydomain.com'.$path ) ;
     header("Content-type: application/pdf");
     header("Content-Disposition: attachment; filename=".$file);
     readfile($filepath);

 }else{
     echo "file not found using path ".$path." and file is ".$file;
 }
输出是 使用路径/documents/6/Doc1.pdf找不到文件,文件为Doc1.pdf

但是文件确实存在,并且在目录中-有什么想法吗

好的,我很高兴地报告,雅罗斯拉夫确实帮助我解决了这个问题。他的方法工作得很好,但要把所有目录的内容排好是很困难的。最后,我花了几个小时玩弄组合来让它工作,但他给出的原理很有效。谢谢

我想保护pdf文件不被直接链接,而是让我的登录用户能够访问它


在流式传输PDF内容之前,请检查以确保有经过身份验证的用户。

最好的方法是使用htaccess保护该文件夹,如您所述。因此,您将所有pdf文件放在pdf/文件夹中,并在同一个pdf文件夹中输出.htaccess文件:

RewriteEngine on
RewriteRule .* your-php-script.php
现在,此文件夹中的url无法访问任何文件。对该文件夹中每个文件的每个请求都将返回您的-php-script.php脚本返回的内容。在your-php-script.php中,您可以执行以下操作:

//Check if user has right to access the file. If no, show access denied and exit the script.
$path = $_SERVER['REQUEST_URI'];
$paths = explode('/', path);
$lastIndex = count($paths) - 1;
$fileName = $paths[$lastIndex]; // Maybe add some code to detect subfolder if you have them
// Check if that file exists, if no show some error message
// Output headers here
readfile($filename);
现在,如果用户打开domain.com/pdf/nsa-secrets.pdf,Apache将运行您的-php-script.php。脚本将变量$\u SERVER['REQUEST\u URI']设置为“domain.com/pdf/nsa secrets.pdf”。您获取最后一部分(文件名)并将其输出给用户(或不输出)

这将阻止任何人通过知道URL直接从internet访问文件。如果有人可以直接访问您服务器上的文件,这不会阻止他们。另一方面,我认为任何共享主机都会阻止用户获取其他客户端的文件。唯一的方法就是以某种方式攻击服务器。但是,我们变得非常偏执,如果这可能是你的情况,你不应该使用共享主机摆在首位


如果您无法使htaccess工作,您可以尝试对文件进行模糊处理,因此很难为外部人员发现它们。例如,将文件从mySecretData.pdf更改为djjsdmdkjeksm.pdf。这可能会有一点帮助。

这有点草率,但如果您可以设置MYSQL数据库,它就可以工作。它允许您将URL中的“密码”作为MD5字符串或明文(如果需要)传递。试图在不使用htaccess或现有框架的情况下设置某种安全性有点笨拙。但是,在它知道您已经“验证”之前,它甚至不会将文件附加到流中。我认为,如果您设置一个在本地保存cookie的登录页面,那么您就不需要在URL中传递“密码短语”,这样做可能会更好一些


您在
.htaccess
中尝试过的代码是什么?我要使用的Wolf:Order deny,allow deny from all allow 127.0.0.1,但它是一个共享主机,所以我认为这意味着服务器上的任何人都可以访问它?哦,是的,但它不起作用:)没有必要使用127.0.0.1中的
允许部分,因为只有php尝试访问不受
.htaccess
影响的文件。能否将PDF目录移到web根目录之外?这在大多数共享主机上都是可能的。如果没有“允许发件人”也不起作用,它会给出一条禁止的消息。如果知道URI,这不会停止直接下载pdf?@user1616338它会的,除非文件托管在您的web根上,并通过Apache或其他方式提供服务。如果是这样的话,请将它们移动到webroot之上,或者使用Apache来防止自己为它们服务。这是如何工作的。恐怕我的.htaccess知识不太好。第一行打开Apache的url重写引擎(假设您的服务器使用Apache)。第二条告诉我们,对这个目录中每个文件的查询都应该在内部重定向到php脚本,不管是哪个名为domain.com/pdf/abc.pdf或domain.com/pdf/secret-nsa-presentation.pdf的用户,Apache都会返回您的php脚本。好吧,所以我有类似的东西:RewriteRule上的RewriteEngine^(.*)(pdf)$fileopen.php?file=$1.$2[L]但是我不知道如何通过htaccess将变量传递给php脚本,所以它知道打开reuqest URL的文件实际上是个好主意。您可以按域限制对此文件夹的访问。那么我如何将请求URI写入htaccess?我想到了类似的方法,但如果该人知道PDF的直接URL,则在某种程度上可以提供保护,那么就永远不需要运行脚本,因此密码验证也不会有帮助
    $file = $_GET['file'];
    $pass = $_GET['pass'];
    $download_folder = '../Protected';
    $file = basename($file);
    $filepath = "$download_folder/$file";

    if (file_exists($filepath)) {
        if(CheckUser($pass)){
            header("Content-type: application/octet-stream");
            header("Content-Disposition: attachment; filename=$file");
            session_write_close();
            readfile($filepath);
        } else {
            echo 'Not Authenticated!';
        }
    } else {
        echo 'No File!';
    }

function CheckUser($value){
    $con = mysqli_connect("test.com","test","123456","my_db");
    // Check connection
    if (mysqli_connect_errno()){
        echo "Failed to connect to MySQL: " . mysqli_connect_error();
    }
    $result = mysqli_query($con,"SELECT user FROM pass_table WHERE password =".md5($value).";");
    while($row = mysqli_fetch_array($result)){
        mysqli_close($con);
       //return $row['user'];
       if($row['user']){
           return true;
       }
    }
    mysqli_close($con);
    return false;

}