如果您按表单请求执行此操作,则基本上会消除 CSRF 攻击的能力,并且您可以解决另一个常见问题:多个表单提交。简单来说,如果用户在提交之前要求填写表单,则您的应用程序只接受表单输入。
正常情况下,用户 A 访问您的网站并请求表单 A,获得表单 A 以及表单 A 的唯一代码。当用户提交表单 A 时,必须包括仅适用于表单 A 的唯一代码。
CSRF 攻击的情况下,用户 A 访问您的网站并请求表单 A。同时,他们访问另一个“坏”网站,该网站试图对其进行 CSRF 攻击,使其提交假表单 B。
但是,您的网站知道用户 A 从未请求过表单 B,因此即使他们有表单 A 的唯一代码,表单 B 也会被拒绝,因为他们没有表单 B 的唯一代码,只有表单 A 的代码。您的用户是安全的,您可以放心睡觉。
但是,如果您将其作为持续一个小时(如您上面发布的内容)的通用令牌,则上述攻击可能有效,在这种情况下,您的 CSRF 保护不起作用。这是因为应用程序不知道首先没有请求表单 B。这是通用令牌。CSRF 预防的整个重点是使每个表单令牌对该表单唯一。
编辑:因为您要求更多信息:
1-您不必每个表单请求执行此操作,您可以根据小时/会话等来执行此操作。关键点是向用户提供的秘密值,并在返回时重新提交。另一个网站不知道这个值,因此不能提交虚假表单。
因此,您可以每个请求或每个会话生成令牌:
$data['my_token'] = md5(uniqid(rand(), true));
$_SESSION['my_token'] = $data['my_token'];
<input type="hidden" name="my_token" id="my_token" value="<? php echo $_SESSION['my_token']?>" />
if ($_POST['my_token'] === $_SESSION['my_token'])
{
}
else
{
}
而且因为它是“每个表单” - 您不会收到重复的表单提交 - 因为您可以在第一次表单提交后清除令牌!