php - 将 URL 引用者(来源)限制为根 URL 或同一页面
问题描述
我正在为我的网站构建一个 2FA 系统。
登录位于 example.com 的根目录
2FA 脚本位于 example.com/2FA/verify.php
verify.php 由同一页面上的 2 个部分组成,由 IF THEN ELSE 语句分隔
Part1:输入电子邮件并发送令牌。
Part2:点击发送后,同一页面刷新,用户可以输入自己的令牌并点击验证,然后重定向到授权主页。
我试图限制热链接和对 verify.php 的直接访问为此,我试图将其放在我的页面顶部:
$ref1 = $_SERVER['HTTP_REFERER'];
$ref2 = $_SERVER['PHP_SELF'];
if($ref1 !== 'https://example.com/' || $ref1 !== $ref2) {
header('Location: https://example.com');
session_destroy();
}
对 verify.php 的直接访问效果很好,它被重定向到根目录。不幸的是,当用户输入他的电子邮件并单击发送时,我得到了相同的结果。verify.php 的 part2 应该出现,但被重定向到根目录。
如何修改我的顶级 php 代码片段,以便识别相同的页面来源并且脚本可以完成?
解决方案
您可以做的是使用会话来检查客户是否首先访问了您网站的另一个页面。
在index.php
您允许访问的起始页面上,您可以输入以下内容:
<?php
session_start();
$_SESSION['verifyStatus'] = "AccessGranded";
然后在verify.php
页面上您可以执行以下操作:
<?php
session_start();
if (!isset($_SESSION['verifyStatus']) ||
($_SESSION['verifyStatus'] != "AccessGranded")) {
header('Location: https://example.com');
die;
}
所有这一切都是检查客户端是否在index.php
页面之前访问过该verify.php
页面。它不检查它是否就在它之前。
为了确保这index.php
是上一页,我们需要对这个想法进行一些扩展。我将为此使用随机令牌。在index.php
你使用:
<?php
session_start();
$_SESSION['verifyToken'] = bin2hex(random_bytes(16));
在同一页面上,当您链接到时,verify.php
您必须提供此令牌作为参数。像这样:
echo '<a href="verify.php?token='.$_SESSION['verifyToken'].'">Go to verify</a>';
然后我们客户端进入verify.php
页面,你有两个版本的令牌,一个是 in $_SESSION['verifyToken']
,一个是 in $_GET['token']
。它们必须相同。所以verify.php
你可以这样做:
<?php
session_start();
if (!isset($_SESSION['verifyToken']) ||
!isset($_GET['token']) ||
($_SESSION['verifyToken'] != $_GET['token'])) {
header('Location: https://example.com');
die;
}
现在它或多或少地根据需要工作。然后,当您verify.php
再次访问时,您必须再次使用 URL 中的令牌,就像我在上面显示的那样,以便verify.php
再次接受重新加载。
在第二次访问时,verify.php
您可以在会话中重置令牌:
<?php
session_start();
unset($_SESSION['verifyToken']);
这意味着客户端无法verify.php
再次访问,除非该index.php
页面被使用。
推荐阅读
- vue.js - Vue-Mapbox 缩放事件
- android - 在 Android Studio 上模拟比 Lollipop 更早的 Android 版本
- arrays - 我正在尝试将数据帧中的一行数据转换为 numpy 数组。我怎样才能做到这一点?
- sql - Postgres 中的查询对于后来添加的数据比之前添加的数据需要更多时间
- php - Yii2 kartik 文件输入问题,浏览按钮提交表单
- javascript - 使用 LernaJS 时“保留关键字‘接口’”
- python - 在cartopy(python)中获取经度和纬度的鼠标位置
- javascript - Javascript从数据中提取某些字符串
- sql - 根据另一个字段更新记录的动态数量
- c# - Visual Studio 上的 INSERT INTO 命令中的语法错误