我正在阅读Chris Shifflet撰写的一本书“Essential PHP Security”。有一章关于CSRF,作者建议使用令牌来防止CSRF。书中的代码表示要在我们使用的表单中添加令牌
<?php
session_start();
$token = md5(uniqid(rand(), TRUE));
$_SESSION['token'] = $token;
$_SESSION['token_time'] = time();
?>
<form action="buy.php" method="POST">
<input type="hidden" name="token" value="<?php echo $token; ?>" />
<p>
Item:
<select name="item">
<option name="pen">pen</option>
<option name="pencil">pencil</option>
</select><br />
Quantity: <input type="text" name="quantity" /><br />
<input type="submit" value="Buy" />
</p>
</form>
可以使用简单的条件语句检查令牌。
<?php
if (isset($_SESSION['token']) && $_POST['token']== $_SESSION['token'])
{
echo $_POST['token'];
echo "form passed";
}
但上面的代码似乎不起作用。 “表单已通过”消息未显示。上面的代码有什么问题?第一组代码生成令牌,但没有成功消息。
答案 0 :(得分:0)
您需要在session_start();
中添加buy.php
代码的顶部。实施例...
session_start();
if (isset($_SESSION['token']) && $_POST['token']== $_SESSION['token'])
{
echo $_POST['token'];
echo "form passed";
}
答案 1 :(得分:0)
我建议你以功能有效的方式做到这一点:
session_start();
function generate_token(){
$token = uniqid(rand(), true);
$_SESSION['token'] = $token;
$_SESSION['token_time'] = time();
}
//avoid putting script at bottom until required
if($_SERVER['REQUEST_METHOD']=='POST' && !empty($_POST)){
if(isset($_SESSION['token']) && isset($_SESSION['token_time']) &&
isset($_POST['token']))
{
if($_SESSION['token'] == $_POST['token'])
{
$timestamp_ancien = time() - (15*60);
//Si le jeton n'est pas expiré
if($_SESSION['token_time'] >= $timestamp_ancien)
{
//here Instruction
generate_token();//for next call
}else{echo"error3";}
}else{echo"error2";}
}else{echo"error1";}
}
generate_token();
原因:您可以将该功能放在项目中的任何常用位置,并包含或要求该文件使用此代码,而无需在每个地方编写代码。