如何检查一个站点是否没有被直接访问?


How can I check if a site has not been directly reached?

我有一个投票脚本。

但是我有一个小问题。我不希望人们直接到达投票提交页面(投票提交到数据库的页面)。我希望他们只能通过一个特定的链接到达它。

我的投票链接:

<form>
<INPUT id="voteup1" type="BUTTON" VALUE="Vote it up!" ONCLICK="window.location.href='rankup.php?rankid=<? echo $id1; ?>'"> 
<INPUT id="votedown1" type="BUTTON" VALUE="Vote it down!" ONCLICK="window.location.href='rank.php?rankid=<? echo $id1; ?>'"> 
</form>

$id1用于定义已被用户投票的页面。(当投票被添加到数据库中时,这很重要)

我不希望人们直接访问rank.php和rank.php。我该如何预防呢?

HTTP是无状态的没有"直接/间接"到达页面-每个请求都与前一个请求断开连接。

PHP有一种机制来克服这个限制:会话,它反过来使用cookie。

所以,你可以设置一个会话变量,使用作为标志:"can-vote-now",在你的页面上,你将有投票按钮,如果没有设置,禁止投票。

页面上的伪代码:

set_voting_variable_for($poll_identifier);

rankup.php的伪代码:

if (!is_voting_variable_set($poll_identifier)) {
  // redirect away
} else {
  // register the vote
}

哦,请注意使事情发生的页面(所谓的"非幂等"动作-例如增加投票计数)不应该通过GET访问(因为GET保留给显示事物而不改变它们 -"幂等"动作):您可能想要使用POST代替。

最好的方法是使用cookie。只允许在特定时间范围内生成的cookie值用于投票。否则,很容易生成cookie值。

你可以很容易地在PHP会话中做到这一点。

您还应该知道,不建议在GET请求上导致操作发生(更改投票计数)。GET变量应该只在检索具有特定参数的数据时使用。使用POST代替。否则,每次一些搜索机器人偶然发现你的投票脚本,投票就会改变。

您可以使用PHP的引用变量$_SERVER['HTTP_REFERER']来检查引用URL是否属于您。但是你不能百分之百地依赖这个,因为这个信息可能不会被发送,而且它是HTTP头的一部分,如果用户愿意,可以修改它。

会话,如建议的,可能是一个很好的方式去做这件事。我会选择会话而不是cookie,因为用户可以在你的网站上禁用他们的cookie——而且cookie是用户可以编辑的。会话只能由访问你的服务器的人编辑(通常是共享主机)。

我也不同意你这样做。目前,您依赖于用户在浏览器中启用JavaScript。有些用户没有启用,有些用户的浏览器不支持。有些用户甚至禁用了这样的页面重定向。

就我个人而言,我宁愿使用一个脚本,而不是使用两个脚本,就像:
<form action="rank.php" method="post">
<input type="submit" value="Vote up!" />
<input type="submit" value="Vote down!" />
</form>

在rank.php中,您检测按下了两个按钮中的哪个,然后相应地运行一个函数。您可以使用会话变量来存储他们将要投票的项目的ID,然后从会话中读取该ID(但要确保转义),以确保ID不会被用户在最后一刻更改。

希望这能给你一些启发。