我已尝试the method suggested on this site以防止重复提交表单,但在提交表单后(表单通过验证)我总是收到错误Invalid secret key!
。问题是什么?
PHP:
<?php
.
.
.
session_start();
$secret = md5(uniqid(rand(), true));
$_SESSION['FORM_SECRET'] = $secret;
// Send Message
if (isset($_POST['send']))
{
$name = strip_tags(trim($_POST['name']));
$email = strip_tags(trim($_POST['email']));
$subject = strip_tags(trim($_POST['subject']));
$message = strip_tags(trim($_POST['message']));
$valid_name = $name=='' || (mb_strlen($name) > 2 && preg_match('/^\p{L}+$/u', $name));
$valid_email = filter_var($email, FILTER_VALIDATE_EMAIL);
$valid_subject = $subject!='';
$valid_message = $message!='';
if ($valid_name && $valid_email && $valid_subject && $valid_message) {
$form_secret = isset($_POST['form_secret'])?$_POST['form_secret']:'';
if(isset($_SESSION['FORM_SECRET'])) {
if(strcasecmp($form_secret, $_SESSION['FORM_SECRET']) == 0) {
sendEmail($name, $email, $name, $email, $subject, $message, $support_email);
$PAGE_MESSAGE = "Message has been sent!";
unset($_SESSION['FORM_SECRET']);
} else {
//Invalid secret key
$PAGE_ERROR = "Invalid secret key!";
}
} else {
//Secret key missing
$PAGE_ERROR = "Form data has already been processed!";
}
} else {
$PAGE_ERROR = "Error (not valid)!";
}
}
}
?>
HTML:
<form enctype="multipart/form-data" method="POST">
<input type="hidden" name="form_secret" id="form_secret" value="<?php echo $_SESSION['FORM_SECRET'];?>" />
.
.
.
<input type="submit" name="send" value="Send" />
答案 0 :(得分:3)
在example you link to作者建议这样做:
if(isset($_SESSION["FORM_SECRET"])) {
if(strcasecmp($form_secret, $_SESSION["FORM_SECRET"]) === 0) {
但在你的例子中,你这样做:
if(isset($_SESSION['FORM_SECRET'])) {
if(strcasecmp($form_secret, $_SESSION['FORM_SECRET']) == 0) {
请注意,在原始版本中,正在使用===
比较运算符,但在您的正在使用==
。
此外,在您的表单中,执行此操作时form_secret
的值是否实际设置为:
<input type="hidden" name="form_secret" id="form_secret" value="<?php echo $_SESSION['FORM_SECRET'];?>" />
在我看来,如果不知道表单的大型结构,HTML&amp; PHP这很难调试。但我的想法基于我们的PHP有这个:
session_start();
$secret = md5(uniqid(rand(), true));
$_SESSION['FORM_SECRET'] = $secret;
但是表单会在下面处理。每次执行的操作都会重置$_SESSION['FORM_SECRET']
的值。而是需要将大量代码与HTML表单页面放在一起。也许是这样的:
<?php
session_start();
$secret = md5(uniqid(rand(), true));
$_SESSION['FORM_SECRET'] = $secret;
?>
<form enctype="multipart/form-data" method="POST">
<input type="hidden" name="form_secret" id="form_secret" value="<?php echo $_SESSION['FORM_SECRET'];?>" />
.
.
.
<input type="submit" name="send" value="Send" />
然后在PHP中处理表单,这应该是唯一与会话相关的行:
<?php
.
.
.
session_start();
// Send Message
if (isset($_POST['send']))
{
整个想法是<input type="hidden" name="form_secret"…
在传递到$secret = md5(uniqid(rand(), true));
时设置为$_SESSION['FORM_SECRET']
值。然后session_start();
允许您的PHP获取$_SESSION['FORM_SECRET']
&amp;的价值采取行动。
这个想法是表单隐藏form_secret
值&amp; $_SESSION['FORM_SECRET']
具有类似的秘密设置。事实上,HTML表单在表单页面的每个负载上为其创建了一个新值,这使您可以在隐藏值和表单中嵌入表单中的内容进行比较。会议本身。