在 PHP 中确定引用

确定发送或调用(通过 AJAX)当前页面的最可靠和安全的方法是什么。我不想使用 $_SERVER['HTTP_REFERER'],因为它缺乏可靠性,而且我需要调用的页面只能来自我站点上的请求。

编辑: 我希望验证一个脚本,预先一系列的行动是从我的网站页面调用。

156150 次浏览

The REFERER is sent by the client's browser as part of the HTTP protocol, and is therefore unreliable indeed. It might not be there, it might be forged, you just can't trust it if it's for security reasons.

If you want to verify if a request is coming from your site, well you can't, but you can verify the user has been to your site and/or is authenticated. Cookies are sent in AJAX requests so you can rely on that.

There is no reliable way to check this. It's really under client's hand to tell you where it came from. You could imagine to use cookie or sessions informations put only on some pages of your website, but doing so your would break user experience with bookmarks.

We have only single option left after reading all the fake referrer problems: i.e. The page we desire to track as referrer should be kept in session, and as ajax called then checking in session if it has referrer page value and doing the action other wise no action.

While on the other hand as he request any different page then make the referrer session value to null.

Remember that session variable is set on desire page request only.

Using $_SERVER['HTTP_REFERER']

The address of the page (if any) which referred the user agent to the current page. This is set by the user agent. Not all user agents will set this, and some provide the ability to modify HTTP_REFERER as a feature. In short, it cannot really be trusted.

if (!empty($_SERVER['HTTP_REFERER'])) {
header("Location: " . $_SERVER['HTTP_REFERER']);
} else {
header("Location: index.php");
}
exit;

What I have found best is a CSRF token and save it in the session for links where you need to verify the referrer.

So if you are generating a FB callback then it would look something like this:

$token = uniqid(mt_rand(), TRUE);
$_SESSION['token'] = $token;
$url = "http://example.com/index.php?token={$token}";

Then the index.php will look like this:

if(empty($_GET['token']) || $_GET['token'] !== $_SESSION['token'])
{
show_404();
}


//Continue with the rest of code

I do know of secure sites that do the equivalent of this for all their secure pages.