如何将在一个PHP表单上生成的令牌传递给处理它的表单


How can I pass a token generated on one PHP form to a form that processes it?

我试图通过在每个表单上生成一个唯一的令牌来保护我的表单免受CSRF攻击。我的表单上有一个隐藏的字段,它生成一个独特的令牌,如下所示:

public static function generateToken() {
        return $_SESSION['token'] = md5(uniqid(mt_rand(), TRUE));
}

我知道md5是贬值的,不应该使用,因为它不像那样随机

base64_encode(openssl_random_psuedo_bytes(32));

但我目前还没有安装ssl,我会处理这个问题。但我的主要问题是,在生成该令牌后,它被存储到用户当前所在的会话中,如下所示:

$_SESSION['token'] = $_POST['token'];

它获取其中包含生成的令牌的字段的值。现在我已经将该令牌存储到会话中,我需要找出将其发送到处理文件的方法。我在这个表单上有很多字段,所以在一个if()语句中检查每一件事看起来会有点奇怪。我想我想说的是,我如何在处理数据的表单上检查此令牌,如果该令牌与表单上生成的令牌不同,我可以拒绝该数据吗?只是使用die()来终止处理脚本?

我还想知道我是否需要这样做——我已经阅读了CSRF,但我想最糟糕的情况是,有人可能会更改一些发送处理的信息,这就是为什么我想传递令牌来检查数据,并在发生这种情况时拒绝数据。

<form name="form1" action="processing.php" method="POST" enctype="multipart/form-data">

这就是我所说的其他文件。PHP并不是全部在一个地方,我通过$_POST方法获得处理脚本上的所有内容。

  1. 在服务器端生成并保存令牌(sql或其他..)
  2. 使用令牌创建cookie(客户端)
  3. 提交表单时,从cookie中检索令牌
  4. 如果cookie与保存的令牌相同,那没关系

生成令牌:

$formName = "signin"; // name of the form 
$ip       = get_ip(); // create a function to get the ip of the user
$salt     = "8077_(-(àyhvboyr(à"; // uniq secret salt
$token    = md5(sha1($salt.$ip).sha1($salt.$formName));
...
if(empty($_COOKIE['token'])){ // if(empty($_SESSION['token'])){ 
    setcookie("token",$token, time()+3600*1); // use with cookie // time()+3600*1 = now + 1 hour
    $_SESSION['token'] = $token; // OR use with session
}else{
    // when the form is submit regenerate the token and compare with the request token
    if($_COOKIE['token'] == $token){ // OR if($_SESSION['token'] == $token){
       // request from server - ok
       // ...
    }else{
        // bad request
        setcookie("token",0); // destruct cookie
        $_SESSION['token'] = "";  // OR destruct session
        // redirect at the first form
    }
}

<form>
    // if you want use the token directly in your form, add this :
    <input type="hidden" name="token" value="<?php echo $token ?>" />
</form>
$formName = "signin"; // name of the form
$ip       = get_ip(); // create a function to get the ip of the user
$salt     = "8077_(-(àyhvboyr(à"; // uniq secret salt
$token    = md5(sha1($salt.$ip).sha1($salt.$formName));
$_SESSION["token"]=$token;
...
<form action="submit.php" >
// if you want use the token directly in your form, add this :
<input type="hidden" name="token" value="<?php echo $token ?>" />
</form>

在submit.php中,我们需要写一些类似的东西

if($_SESSION['token'] == $_POST['token']){ 
   // request from server
}else{
   // external request
}