php - 如何防止直接访问php页面但重定向时可以访问
问题描述
我想阻止直接访问我的错误页面,404.php
但我希望在从其他页面重定向时可以访问该页面。
就像我的网站名称一样example.com/index.php
,如果任何用户以任何方式输入错误,example.com/ind.php
它将被重定向到我的文件404.php
中,以便在我.htaccess
使用过的文件中执行此操作。
另外,假设在我的index.php
文件中,当单击任何产品时,我正在显示一些产品,它将我product.php?pid=4
带到pid
包含.id
id!=4
404.php
一切都很好,但是如果我访问example.com/404.php
它会向我显示页面,我只希望用户何时直接使用example.com/404.php
它将重定向到index.php
文件。而已。
# enable url rewriting
RewriteEngine On
ErrorDocument 404 http://localhost/news_21_off/404.php
索引.php
$sql = "select * from products";
$res = mysqli_query($co,$sql);
$rs = mysqli_fetch_assoc($res);
$res_id = $rs['id'];
<a href="products.php?pid=<?php echo $res_id; ?>">Product</a>
产品.php
if(isset($_GET['pid']) && $_GET['pid']=='4'){
echo 'correct';
}else{
header('location:404.php');
}
404.php
<h1>My 404 page</h1>
到目前为止,我还没有找到这样做的方法。
解决方案
到此为止的一切工作都很好...
其实我觉得不是...
...防止直接访问 php 页面,但可以在重定向时访问
这不仅仅是任何 PHP 页面。这是您的 404“未找到”错误文档。
首先,您不应该在外部 3xx 重定向到您的错误文档。错误文档应该在同一个请求中提供(“内部子请求”)。这是您的问题的根本原因。
重定向请求是一个完全独立的请求,与“直接请求”几乎没有区别,这自然会使可靠地阻止直接请求“不可能”。但是,您真的需要阻止对 404 错误文档的“直接请求”吗?(见下文...)
ErrorDocument 404 http://localhost/news_21_off/404.php
通过在指令中指定一个绝对 URL(即带有方案 + 主机名)ErrorDocument
,Apache 将触发 302 外部重定向到指定的 URL。除非您在 PHP 代码中手动发送 404“未找到”状态(没有证据表明这里)。
仅仅因为 Apache 允许您“重定向”到错误文档,并不意味着您应该这样做。如Apache 文档中所述:
请注意,当您指定一个
ErrorDocument
指向远程 URL(即前面带有 http 等方法的任何内容)时,Apache HTTP Server 将向客户端发送重定向以告诉它在哪里可以找到文档,即使文档最终位于同一台服务器上。这有几个含义,最重要的是客户端不会收到原始错误状态代码,而是会收到重定向状态代码。这反过来又会混淆网络机器人和其他尝试使用状态代码来确定 URL 是否有效的客户端。
此外,通常与触发 404 的 URL 相关的所有有用的 PHP 超全局变量(从 Apache 传递)都将丢失(例如$_SERVER['REDIRECT_STATUS']
、$_SERVER['REDIRECT_URL']
等),因为如上所述,重定向请求是一个完全独立的请求。
99.99% 的情况下,您应该在ErrorDocument
指令中使用根相对 URL 路径,以便 Apache 触发错误文档的内部子请求,例如:
ErrorDocument 404 /news_21_off/404.php
header('location:404.php');
同样,您也不应该“重定向”到 PHP 代码中的错误文档。
在 PHP 中,有多种方法可以解决这个问题。您可以简单地include()
在您希望为 404 提供服务的代码中的点处提供错误文档。
例如,在您的products.php
脚本中:
<?php
$pid = $_GET['pid'] ?? null;
if ($pid == '4') {
echo 'correct';
} else {
// 404 Not Found
include($_SERVER['DOCUMENT_ROOT'].'/news_21_off/404.php');
exit();
}
但是,上面不会向客户端发送 404 HTTP 状态代码。在您的 PHP 404 错误文档中,您应该设置 HTTP 状态以确保 PHP 发送 404 状态以及何时/如果用户直接访问该文档。
例如,在您的404.php
脚本中:
<?php
http_response_code(404);
?>
<h1>My 404 page</h1>
顺便说一句,在 PHP 脚本中设置 HTTP 状态代码将覆盖 Apache 在提供错误文档时可能设置的任何状态。
现在,回到你最初的问题......
我想阻止直接访问我的错误页面 404.php
为什么?
实施上述更改后,如果用户确实“直接访问”您的 404 错误文档,他们只会收到 404 并看到相同的响应,就好像他们请求了任何其他不存在的文档一样。
因此,除非您有特定要求,否则您无需在这里做任何其他事情。
推荐阅读
- python - Django ORM 使用字典数组排除记录
- mysql - 如何在 React 页面上显示存储在 MySQL 中的图像
- elasticsearch - 使用 logstash 在弹性搜索中将两个索引合并为第三个索引
- sql - SQL LEFT_JOIN 表在自身上,同时替换列
- python-3.x - 我已经在 python 中安装了 cvlib 但仍然无法导入它
- powerbi - 图表显示每月间隔和所有其他数据的单个条形图
- linux - 使用 xargs 将文件从本地系统复制到 docker 容器中
- http - NativeScript Vue 中的 Http 拦截器
- python - 如何使用单元格中的字符串重新排序熊猫中的数据框?
- google-cloud-platform - 使用部署管理器在谷歌存储桶中创建一个文件夹