Php 将URL引用者(源)限制为根URL或同一页面

Php 将URL引用者(源)限制为根URL或同一页面,php,Php,我正在为我的网站建立一个2FA系统 登录名位于example.com的根目录上 2FA脚本位于example.com/2FA/verify.php中 php由同一页面上的两个部分组成,由IF-THEN-ELSE语句分隔 第1部分:输入电子邮件并发送令牌 第2部分:单击发送后,同一页面刷新,用户可以输入他的令牌并单击验证,然后重定向到授权主页或未授权主页 我正试图限制热链接和对verify.php的直接访问 为此,我尝试将以下内容放在我的页面顶部: $ref1 = $_SERVER['HT

我正在为我的网站建立一个2FA系统

  • 登录名位于example.com的根目录上

  • 2FA脚本位于example.com/2FA/verify.php中

php由同一页面上的两个部分组成,由IF-THEN-ELSE语句分隔

  • 第1部分:输入电子邮件并发送令牌

  • 第2部分:单击发送后,同一页面刷新,用户可以输入他的令牌并单击验证,然后重定向到授权主页或未授权主页

我正试图限制热链接和对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的第2部分,但会重定向到根目录


如何修改顶部的php代码段,以便识别相同的页面来源并完成脚本?

您可以使用来检查客户端是否首先访问了站点的另一个页面

在允许访问的起始
index.php
页面上,可以放置以下内容:

<?php

session_start();

$_SESSION['verifyStatus'] = "AccessGranded";
不过,所有这一切只是检查客户机在
verify.php
页面之前是否访问了
index.php
页面。它不会检查它是否就在它之前

为了确保
index.php
是上一页,我们需要对这个想法进行一些扩展。我将使用一个随机令牌。在
index.php
中,您可以使用:

<?php

session_start();

$_SESSION['verifyToken'] = bin2hex(random_bytes(16));
然后我们让客户端进入
verify.php
页面,您有两个令牌版本,一个在
$\u会话['verifyToken']
中,另一个在
$\u GET['token']
中。它们一定是一样的。因此,在
verify.php
中,您可以执行以下操作:

<?php

session_start();

if (!isset($_SESSION['verifyStatus']) || 
    ($_SESSION['verifyStatus'] != "AccessGranded")) {
     header('Location: https://example.com');
     die;
}
<?php

session_start();

if (!isset($_SESSION['verifyToken']) ||
    !isset($_GET['token']) ||   
    ($_SESSION['verifyToken'] != $_GET['token'])) {
     header('Location: https://example.com');
     die;
}

这意味着客户端无法再次访问
verify.php
,除非使用
index.php
页面。

请参阅:因此不建议使用这种方式。为什么您在热链接或直接访问方面会遇到问题?请阅读问题。直接访问是问题所在。首先访问verify.php工作正常,正确地检查了referer。但是当verify.php上的脚本的第二部分被执行时,不是完成,而是被重定向到根目录,因为这次它将引用者视为页面(verify.php)本身。我的第一个评论是通知您,
HTTP\u REFERER
不可靠,不应以这种方式使用。第二条评论只是出于好奇:为什么要阻止直接访问?评论通常不能回答你的问题。我很感激你的评论并理解你的观点。现在,如何修改代码段,使verify.php在脚本exec重新加载时不会被重定向?只是实现了它。工作起来很有魅力。答案很好,逻辑也是正确的。非常感谢你的努力。请联系我每DM,我很高兴有进一步的交流与您。祝你有美好的一天。
<?php

session_start();

if (!isset($_SESSION['verifyToken']) ||
    !isset($_GET['token']) ||   
    ($_SESSION['verifyToken'] != $_GET['token'])) {
     header('Location: https://example.com');
     die;
}
<?php

session_start();

unset($_SESSION['verifyToken']);