php - 保护文件不被直接访问

标签 php apache .htaccess mod-rewrite url-rewriting

我有一个用于保存文件的文件夹。可以从网页访问这些文件。假设该目录类似于 manual/fileName.pdf

我还有一个页面显示 manual/ 文件夹中存储的文件列表,该页面使用用户 session 进行保护。所以你必须先登录才能访问该页面。

我读到,通过在文件夹中放置一个 .htaccess,我可以阻止用户直接访问文件。但现在我什至无法从该列表页面访问它们。

这是我在 .htaccess 中写的:

RewriteEngine on
RewriteRule .documentation.php

这是我的文件列表脚本:

if ($handle = opendir('manual')) {
   while (false !== ($entry = readdir($handle))) {
     if ($entry != "." && $entry != "..") {
        if (!preg_match('/.php/', $entry) && !preg_match('/.htaccess/', $entry)) //prevent some file to be shown
            {echo "<a href='manual/$entry' target='_blank'>$entry</a><hr>";}
         }
     }
     closedir($handle);
}

知道如何访问这些文件吗?

最佳答案

通常,从文档根目录中提供 protected 文件不是一个好主意。特别是,当用户需要登录才能查看/访问它们时。当您将服务委托(delegate)给网络服务器时,您失去了以编程方式检查用户是否登录的能力,因为 Apache 网络服务器无法知道用户是否在您的 PHP 应用程序中进行了身份验证。一旦用户知道了文件 URL,她就可以在不登录系统的情况下访问该文件。

有一个解决方法,我会帮助您完成。但我强烈建议您将文件放在您的 webroot 之外,并开发一个脚本以在访问时传送它们。这样您就可以在提供文件时检查经过身份验证和授权的 session 。

但是,如果您坚持采用这种方式,则有一个解决方法。让我们布置一个示例目录结构:

/path/to/web/document/root
├── manual
│   └── .htaccess
│   └── file1.pdf  # protected
│   └── file2.pdf  # protected
│   └── file3.epub # protected
├── documentation.php
├── listing.php    # protected
└── .htaccess

您希望manual/ 目录中的文件受到保护,并且只有在用户登录时才能访问。因此,您将以下指令放入 manual/.htaccess 文件中:

RewriteEngine on
RewriteRule ^ /documentation.php [R]
# Your own rewrite rule has a syntax error and 
# causes a 500 internal error

这会将所有请求重定向到父目录中的documentation.php 文件。如果不需要外部重定向,请删除 R 标志。

如您所说,现在的问题是对 manual/ 中文件的任何请求都被重定向到文档文件。

解决方法是检查 HTTP_REFERER header 并确保请求来自 listing.php 文件。

RewriteEngine on

# Feel free to change example.com with your own domain    
RewriteCond %{HTTP_REFERER} !^http://www.example.com/listing.php$
RewriteRule ^ /documentation.php [R]

这样,对 manual/file2.pdf 的任何直接请求都会导致重定向到 documentation.php,但是如果用户单击 中的链接listing.php 她可以毫无问题地访问该文件。

如果您需要使 referer 条件更通用,请参阅这篇文章:
Referrer Checking with .htaccess

注意 that a user can easily spoof the HTTP_REFERER header从而无需登录即可访问文件。实现这一点的唯一真正万无一失的方法就是我在本文开头所说的。

您可能还想使用基本的 http 身份验证来保护 manual/ 目录。但是这样,用户需要输入另一个用户名/密码组合才能访问该文件夹。

关于php - 保护文件不被直接访问,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41646761/

相关文章:

php - Yahoo 是否支持 oauth 的状态参数?

apache - 我如何使用 mod_pagespeed 重写 HTML 以从我的 CDN 提供图像?

linux - 如何阻止直接访问我在 Apache 中的自定义 404 页面?

php - .htaccess 重写是冲突的/漂亮的 url

apache - 我如何强制 URL 区分大小写

php - $_SERVER ['HTTP_REFERER' ] 在移动网络应用程序中的等效功能是什么

PHP:脚本大小限制

php - 核心数据快速同步mysql数据库

php - proc_open() 失败,返回 'Permission denied'

PHP Docker 容器不处理文件而是提供源代码