【问题标题】:how to encrypt file download path如何加密文件下载路径
【发布时间】:2011-06-16 08:48:36
【问题描述】:

我想允许用户从我的一个文件夹中下载 pdf 文件。当用户“鼠标悬停”到文件下载图标时,有什么办法可以隐藏用户的下载路径?

建议使用 PHP 或 javascript 的任何方法。

【问题讨论】:

  • 没有。总有一种方法可以找出您从哪里下载文件(例如检查 HTTP 标头)。为什么要这样做?
  • 我不希望用户直接访问文件,如果下载链接是文件名 MP(1).pdf 则意味着该文件夹将有 MP(2).pdf、MP(3)。 pdf 我不希望我的客户访问其他文件。
  • 然后通过 PHP 脚本提供文件(如 @Ignacio 建议的那样)并将文件存储在 Web 根目录之外。
  • 是的,我想我将不得不使用那个 PHP 脚本。谢谢。

标签: php javascript


【解决方案1】:

将浏览器指向一个 PHP 脚本,传递一个代表要下载的文件名的键。解码密钥,然后send the file via the PHP script

【讨论】:

    【解决方案2】:

    在某些时候,您必须为浏览器提供真正的 URI,以便它可以获取文件。 试图隐瞒是没有意义的。

    我不相信这是真的。有一种简单的方法可以使用 PHP 的 fpassthru 保护服务器上的文件免遭非特权下载。如果您有一个名为 download.php 的文件,其内容如下:

    <?php
    
    /**
     * Make sure the downloads are *not* in a publically accessible path, otherwise, people
     * are still able to download the files directly.
     */
    $filename = '/the/path/to/your/files/' . basename( $_GET['filename'] );
    
    /**
     * You can do a check here, to see if the user is logged in, for example, or if 
     * the current IP address has already downloaded it, the possibilities are endless.
     */
    
    
    if( file_exists( $filename ) ) {
        /** 
         * Send some headers indicating the filetype, and it's size. This works for PHP >= 5.3.
         * If you're using PHP < 5.3, you might want to consider installing the Fileinfo PECL
         * extension.
         */
        $finfo = finfo_open( FILEINFO_MIME );
        header( 'Content-Disposition: attachment; filename= ' . basename( $filename ) );
        header( 'Content-Type: ' . finfo_file( $finfo, $filename );
        header( 'Content-Length: ' . filesize( $filename ) );
        header( 'Expires: 0' );
        finfo_close( $finfo );
    
        /**
         * Now clear the buffer, read the file and output it to the browser.
         */
        ob_clean( );
        flush( );
        readfile( $filename );
        exit;
    }
    
    header( 'HTTP/1.1 404 Not Found' );
    
    echo "<h1>File not found</h1>";
    exit;
    

    您可以使用 ?filename=test.foo 调用 download.php,它会下载 /the/path/to/your/files/test.foo,这是不可公开访问的。

    【讨论】:

    • 直到他们通过?filename=../../../../../../../etc/passwd...
    • 向此代码添加一些健全性检查。否则一个很好的答案。
    • @Ignacio:刚刚注意到:basename("../../../../../../../etc/passwd") 返回 passwd,而不是 /etc/passwd
    • 在这种情况下,此脚本最多只能包含几千个文件,尽管这可能不是问题。
    • @Ignacio 确实,有基本名称可以实现这一点。是的,它仅限于几千个文件,但如果这是一个问题,应该很容易破解它以支持多个文件夹。
    【解决方案3】:

    在某些时候,您必须为浏览器提供真正的 URI,以便它可以获取文件。试图隐瞒是没有意义的。

    如果您想限制谁可以访问它,请设置某种时间限制凭据并在允许访问下载之前进行身份验证。

    【讨论】:

    • 如果我必须提供真实的 URI,是否可以使用 .htaccesss 文件阻止对文件夹的直接访问。
    • 如果您的意思是“是否可以停止服务器提供带有 .htaccess 文件的目录列表文档”,那么可以。 Options -IndexesIIRC.
    • 但是你确定客户端可以通过链接访问文件,但不能通过HTTP请求(直接路径)。
    • 链接只是使浏览器发出 HTTP 请求的一种方式。没有可靠的方法来查看他们是点击链接还是直接请求链接。这就是为什么我说你必须添加某种身份验证。
    【解决方案4】:

    是的,当用户点击指向“#”的链接时,您可以使用 javascript 重定向用户,例如

    <a href="#">Secret File</a>
    

    但是,这是没有意义的,因为总是可以跟踪正在下载的文件(例如,通过使用 HTTP 嗅探器或其他工具)。从本质上讲,你所要求的是不可能和不合理的。

    如果您需要确保只有某些人可以访问该文件,请让他们登录并检查凭据,然后再向他们提供数据。隐藏路径不是要走的路。

    【讨论】:

      【解决方案5】:
      Before Passing FilePath it to download_file() fucntion. Append the path to file id. Like Below.
      
      
      $FilePaths='../Uploaded Files/'.$FilePath;
      
      download_file($FilePaths);
      
      function download_file( $fullPath )
      {
      
        // Must be fresh start
        if( headers_sent() )
          die('Headers Sent');
      
        // Required for some browsers
        if(ini_get('zlib.output_compression'))
          ini_set('zlib.output_compression', 'Off');
      
        // File Exists?
        if( file_exists($fullPath) ){
      
          // Parse Info / Get Extension
          $fsize = filesize($fullPath);
          $path_parts = pathinfo($fullPath);
          $ext = strtolower($path_parts["extension"]);
      
          // Determine Content Type
          switch ($ext) {
            case "pdf": $ctype="application/pdf"; break;
            case "exe": $ctype="application/octet-stream"; break;
            case "zip": $ctype="application/zip"; break;
            case "doc": $ctype="application/msword"; break;
            case "xls": $ctype="application/vnd.ms-excel"; break;
            case "ppt": $ctype="application/vnd.ms-powerpoint"; break;
            case "gif": $ctype="image/gif"; break;
            case "png": $ctype="image/png"; break;
            case "jpeg":
            case "jpg": $ctype="image/jpg"; break;
            default: $ctype="application/force-download";
          }
      
          header("Pragma: public"); // required
          header("Expires: 0");
          header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
          header("Cache-Control: private",false); // required for certain browsers
          header("Content-Type: $ctype");
          header("Content-Disposition: attachment; filename=\"".basename($fullPath)."\";" );
          header("Content-Transfer-Encoding: binary");
          header("Content-Length: ".$fsize);
          ob_clean();
          flush();
          readfile( $fullPath );
      
        } 
        else
          die('File Not Found');
      
      }
      

      【讨论】:

        【解决方案6】:

        就像其他人指出的那样,在某些时候,您必须显示 URL,但如果您只想将其从状态栏中隐藏,您可以这样做:

        <a href="http://example.org" onmouseover="window.status='Add something here.'; return true;" onmouseout="window.status=''; return true;">Description</a>
        

        【讨论】:

          猜你喜欢
          • 2021-11-06
          • 2015-11-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-07-16
          • 1970-01-01
          • 2020-01-22
          • 2017-05-14
          相关资源
          最近更新 更多