uniqid(mt_rand(),true)
不适用于 nonce 值:
http://php.net/manual/en/function.mt-rand.php
它使用具有已知特性的随机数生成器,使用 » Mersenne Twister,生成随机数的速度比 libc rand() 提供的平均速度快四倍。
http://php.net/manual/en/function.uniqid.php
他的函数不会生成加密安全值,并且不应用于加密目的。如果您需要加密安全值,请考虑改用 random_int()、random_bytes() 或 openssl_random_pseudo_bytes()。
random_bytes
并openssl_random_pseudo_bytes
返回不可打印的字符,但您可以将它们转换为十六进制表示:
bin2hex(random_bytes($length))
确保 nonces 缓存存储对其他用户不可用。例如,PHP 会话通常保存为 /tmp 文件夹中的文件。如果您使用的是 SESSIONS,请覆盖其默认行为:
http://php.net/manual/en/class.sessionhandlerinterface.php
无论如何,我开发并发布了一个 nonces 库:
这是您可以使用该库创建带有 nonce 的表单的方法:
<?php
require __DIR__ . '/../vendor/autoload.php';
$form = new \pedroac\nonce\Form\NonceForm(
'token',
new \pedroac\nonce\NoncesManager(
new \Symfony\Component\Cache\Simple\PdoAdapter($pdo)
)
);
if ($form->isSubmittedInvalid()) {
/**
* handle failure
*/
}
if ($form->isSubmittedValid()) {
/**
* handle the success
*/
}
?>
<form method="POST">
<?= new HtmlNonceField($form) ?>
<input type="submit" name="myform" value="Submit" />
</form>
你也可以这样做:
<?php
require __DIR__ . '/../vendor/autoload.php';
$manager = new \pedroac\nonce\NoncesManager(
new \Symfony\Component\Cache\Simple\PdoAdapter($pdo)
);
$lastNonceName = $_SESSION['nonce_name'];
if(isset($_POST[$lastNonceName]) && $manager->verifyAndExpire($lastNonceName, $_POST[$lastNonceName])) {
// handle success
}
$nonce = $manager->create();
session_start();
$_SESSION['nonce_name'] = $nonce->getName();
?>
<form method="post">
<input type="hidden"
name="<?= htmlspecialchars($nonce->getName()) ?>"
value="<?= htmlspecialchars($nonce->getValue()) ?>" />
<input type="submit" name="myform" value="Submit" />
</form>