添加一个表单字段并添加一个数学问题来阻止机器人? :(
Adding a form field add with a mathematical question to stop bots? :(
美好的一天,我正在寻求这方面的帮助。在我的 PHP 页面上,我想添加一个简单的数学问题(例如:5+2)来阻止垃圾邮件。请问有什么推荐吗?将不胜感激,如果有什么方法可以改进我的代码,也请随意。
这是我的 PHP 页面和表单字段:
<div class="col-xs-12 col-md-8">
<?php
// Contact Form
function contact_form() {
if(isset($_POST["name"]) && $_POST["name"] != "")
{
if(!filter_var($_POST["mail"], FILTER_VALIDATE_EMAIL)) {
echo "<div class='error'>The email address is not valid</div>";
return;
}
if($_POST["name"] == "" || $_POST["mail"] == "" || $_POST["message"] == "") {
echo "<div class='error'>Informations are missing</div>";
return;
}
$name = htmlentities($_POST["name"]);
$message = htmlentities($_POST["message"]);
$message = wordwrap($message, 70, "\r\n");
$to = '@hotmail.com';
$subject = 'Message of '.$name.'';
$headers = 'From: ' . "\r\n" .
'X-Mailer: PHP/' . phpversion();
$message_final = "Someone sent you a message \nNom : ".$name."\nCourriel : ".$_POST["mail"]."\n\n\n".$message;
if(mail($to, $subject, $message_final, $headers)) {
echo "<div class='success'>Your message was sent. Thank you!</div>";
return;
} else {
echo "<div class='error'>There was an error. You message was not sent</div>";
return;
}
}
}
contact_form();
?>
<form method="post">
<div class="form-group">
<label for="name">Name</label>
<input type="text" class="form-control" id="name" name="name" placeholder="Enter your name" required>
</div>
<div class="form-group">
<label for="name">Email</label>
<input type="email" class="form-control" id="mail" name="mail" placeholder="Enter your email" required>
</div>
<div class="form-group">
<label for="message">Message</label>
<textarea id="message" name="message" class="form-control" rows="3" required></textarea>
</div>
<div class="form-group">
<button type="submit" class="btn btn-default">Send</button>
</div>
</form>
</div>
干杯
我实际上做了一些你描述的事情。有多种方法可以实现这一点,但一种简单的方法是使用生成随机数学问题、散列答案并将散列插入隐藏字段的函数。用户提交表单,您将提交的答案的哈希值与隐藏字段中的哈希值进行比较。您可能还想考虑对表单使用唯一令牌,这样表单就无法 POST 在没有先获得令牌的情况下进入您的网站。
您可以尝试这样的操作:
function mathQuestion($lo, $hi) {
$a = mt_rand($lo, $hi);
$b = mt_rand($lo, $hi);
$c = $a + $b;
$hash = md5($c);
$q = "$a + $b";
return array($q, $hash);
}
function mathQuestionVerify($c, $hash) {
return (md5($c) === $hash);
}
然后,在您的表单中,类似于:
$mathQ = mathQuestion(10, 89);
$mathText = $mathQ[0];
$mathHash = $mathQ[1];
echo "<div><label for='mathquestion'>What is $mathText?</label><input id='mathquestion' name='mathquestion'></div>";
echo "<input type='hidden' name='mathanswer' value='$mathHash'>";
echo "<input type='hidden' name='token' value='$token'>";
以上两个字段是数学相关的。 这里的 token 变量是我从中获取的表单中的 CSRF 令牌。 实际上,这只是我之前描述的唯一表单令牌 - 我也在用户登录时使用 CSRF 令牌.
在上面的示例中,当加载表单时,我们添加了两个数字,每个数字都在 10 到 89 之间。您可以将它们更改为任何您想要的。我使用更广泛的数字来完成不太常见的任务,比如密码重置,因为这不是经常做的事情。对于一般的联系表格,您应该将这些数字保持在较小的范围内 - 可能低于 50。
请注意 md5 不是加密安全的。 sha1 也不是。我实际上也不认为 mt_rand()
是。只是把它扔在那里。我在这种情况下使用 md5,因为我们不处理敏感数据,因此简单、快速的散列函数非常适合我的目的。
我不使用此机制作为我唯一的验证方法,但它肯定可以减缓恶意尝试。如果你想更进一步,你甚至可以使用一个函数将数字问题重写成文本,使机器人更难发送垃圾邮件。
根据您的具体情况,您可以尝试这样的操作:
<div class="col-xs-12 col-md-8">
<?php
// Contact Form
function contact_form() {
if(isset($_POST["name"]) && $_POST["name"] != "")
{
if(!isSet($_POST['mathanswer'] || !mathQuestionVerify($_POST['mathanswer'], $_POST['mathhash'])) {
echo "<div class='error'>Incorrect answer.</div>";
return;
}
if(!filter_var($_POST["mail"], FILTER_VALIDATE_EMAIL)) {
echo "<div class='error'>The email address is not valid</div>";
return;
}
if($_POST["name"] == "" || $_POST["mail"] == "" || $_POST["message"] == "") {
echo "<div class='error'>Informations are missing</div>";
return;
}
$name = htmlentities($_POST["name"]);
$message = htmlentities($_POST["message"]);
$message = wordwrap($message, 70, "\r\n");
$to = '@hotmail.com';
$subject = 'Message of '.$name.'';
$headers = 'From: ' . "\r\n" .
'X-Mailer: PHP/' . phpversion();
$message_final = "Someone sent you a message \nNom : ".$name."\nCourriel : ".$_POST["mail"]."\n\n\n".$message;
if(mail($to, $subject, $message_final, $headers)) {
echo "<div class='success'>Your message was sent. Thank you!</div>";
return;
} else {
echo "<div class='error'>There was an error. You message was not sent</div>";
return;
}
}
}
contact_form();
?>
<form method="post">
<div class="form-group">
<label for="name">Name</label>
<input type="text" class="form-control" id="name" name="name" placeholder="Enter your name" required>
</div>
<div class="form-group">
<label for="name">Email</label>
<input type="email" class="form-control" id="mail" name="mail" placeholder="Enter your email" required>
</div>
<div class="form-group">
<label for="message">Message</label>
<textarea id="message" name="message" class="form-control" rows="3" required></textarea>
</div>
<div class="form-group">
<button type="submit" class="btn btn-default">Send</button>
</div>
<?php
$mathQ = mathQuestion(5, 15); # ask user to add 2 random numbers between 5 & 15
$mathText = $mathQ[0];
$mathHash = $mathQ[1];
echo "<div><label for='mathquestion'>What is $mathText?</label><input id='mathquestion' name='mathquestion'></div>";
echo "<input type='hidden' name='mathanswer' value='$mathHash'>";
?>
</form>
</div>
美好的一天,我正在寻求这方面的帮助。在我的 PHP 页面上,我想添加一个简单的数学问题(例如:5+2)来阻止垃圾邮件。请问有什么推荐吗?将不胜感激,如果有什么方法可以改进我的代码,也请随意。
这是我的 PHP 页面和表单字段:
<div class="col-xs-12 col-md-8">
<?php
// Contact Form
function contact_form() {
if(isset($_POST["name"]) && $_POST["name"] != "")
{
if(!filter_var($_POST["mail"], FILTER_VALIDATE_EMAIL)) {
echo "<div class='error'>The email address is not valid</div>";
return;
}
if($_POST["name"] == "" || $_POST["mail"] == "" || $_POST["message"] == "") {
echo "<div class='error'>Informations are missing</div>";
return;
}
$name = htmlentities($_POST["name"]);
$message = htmlentities($_POST["message"]);
$message = wordwrap($message, 70, "\r\n");
$to = '@hotmail.com';
$subject = 'Message of '.$name.'';
$headers = 'From: ' . "\r\n" .
'X-Mailer: PHP/' . phpversion();
$message_final = "Someone sent you a message \nNom : ".$name."\nCourriel : ".$_POST["mail"]."\n\n\n".$message;
if(mail($to, $subject, $message_final, $headers)) {
echo "<div class='success'>Your message was sent. Thank you!</div>";
return;
} else {
echo "<div class='error'>There was an error. You message was not sent</div>";
return;
}
}
}
contact_form();
?>
<form method="post">
<div class="form-group">
<label for="name">Name</label>
<input type="text" class="form-control" id="name" name="name" placeholder="Enter your name" required>
</div>
<div class="form-group">
<label for="name">Email</label>
<input type="email" class="form-control" id="mail" name="mail" placeholder="Enter your email" required>
</div>
<div class="form-group">
<label for="message">Message</label>
<textarea id="message" name="message" class="form-control" rows="3" required></textarea>
</div>
<div class="form-group">
<button type="submit" class="btn btn-default">Send</button>
</div>
</form>
</div>
干杯
我实际上做了一些你描述的事情。有多种方法可以实现这一点,但一种简单的方法是使用生成随机数学问题、散列答案并将散列插入隐藏字段的函数。用户提交表单,您将提交的答案的哈希值与隐藏字段中的哈希值进行比较。您可能还想考虑对表单使用唯一令牌,这样表单就无法 POST 在没有先获得令牌的情况下进入您的网站。
您可以尝试这样的操作:
function mathQuestion($lo, $hi) {
$a = mt_rand($lo, $hi);
$b = mt_rand($lo, $hi);
$c = $a + $b;
$hash = md5($c);
$q = "$a + $b";
return array($q, $hash);
}
function mathQuestionVerify($c, $hash) {
return (md5($c) === $hash);
}
然后,在您的表单中,类似于:
$mathQ = mathQuestion(10, 89);
$mathText = $mathQ[0];
$mathHash = $mathQ[1];
echo "<div><label for='mathquestion'>What is $mathText?</label><input id='mathquestion' name='mathquestion'></div>";
echo "<input type='hidden' name='mathanswer' value='$mathHash'>";
echo "<input type='hidden' name='token' value='$token'>";
以上两个字段是数学相关的。 这里的 token 变量是我从中获取的表单中的 CSRF 令牌。 实际上,这只是我之前描述的唯一表单令牌 - 我也在用户登录时使用 CSRF 令牌.
在上面的示例中,当加载表单时,我们添加了两个数字,每个数字都在 10 到 89 之间。您可以将它们更改为任何您想要的。我使用更广泛的数字来完成不太常见的任务,比如密码重置,因为这不是经常做的事情。对于一般的联系表格,您应该将这些数字保持在较小的范围内 - 可能低于 50。
请注意 md5 不是加密安全的。 sha1 也不是。我实际上也不认为 mt_rand()
是。只是把它扔在那里。我在这种情况下使用 md5,因为我们不处理敏感数据,因此简单、快速的散列函数非常适合我的目的。
我不使用此机制作为我唯一的验证方法,但它肯定可以减缓恶意尝试。如果你想更进一步,你甚至可以使用一个函数将数字问题重写成文本,使机器人更难发送垃圾邮件。
根据您的具体情况,您可以尝试这样的操作:
<div class="col-xs-12 col-md-8">
<?php
// Contact Form
function contact_form() {
if(isset($_POST["name"]) && $_POST["name"] != "")
{
if(!isSet($_POST['mathanswer'] || !mathQuestionVerify($_POST['mathanswer'], $_POST['mathhash'])) {
echo "<div class='error'>Incorrect answer.</div>";
return;
}
if(!filter_var($_POST["mail"], FILTER_VALIDATE_EMAIL)) {
echo "<div class='error'>The email address is not valid</div>";
return;
}
if($_POST["name"] == "" || $_POST["mail"] == "" || $_POST["message"] == "") {
echo "<div class='error'>Informations are missing</div>";
return;
}
$name = htmlentities($_POST["name"]);
$message = htmlentities($_POST["message"]);
$message = wordwrap($message, 70, "\r\n");
$to = '@hotmail.com';
$subject = 'Message of '.$name.'';
$headers = 'From: ' . "\r\n" .
'X-Mailer: PHP/' . phpversion();
$message_final = "Someone sent you a message \nNom : ".$name."\nCourriel : ".$_POST["mail"]."\n\n\n".$message;
if(mail($to, $subject, $message_final, $headers)) {
echo "<div class='success'>Your message was sent. Thank you!</div>";
return;
} else {
echo "<div class='error'>There was an error. You message was not sent</div>";
return;
}
}
}
contact_form();
?>
<form method="post">
<div class="form-group">
<label for="name">Name</label>
<input type="text" class="form-control" id="name" name="name" placeholder="Enter your name" required>
</div>
<div class="form-group">
<label for="name">Email</label>
<input type="email" class="form-control" id="mail" name="mail" placeholder="Enter your email" required>
</div>
<div class="form-group">
<label for="message">Message</label>
<textarea id="message" name="message" class="form-control" rows="3" required></textarea>
</div>
<div class="form-group">
<button type="submit" class="btn btn-default">Send</button>
</div>
<?php
$mathQ = mathQuestion(5, 15); # ask user to add 2 random numbers between 5 & 15
$mathText = $mathQ[0];
$mathHash = $mathQ[1];
echo "<div><label for='mathquestion'>What is $mathText?</label><input id='mathquestion' name='mathquestion'></div>";
echo "<input type='hidden' name='mathanswer' value='$mathHash'>";
?>
</form>
</div>