php - 如何在没有验证码的情况下保护联系表?

标签 php forms

在我的网站上,我有几个表单,某人(未注册)可以向指定的注册用户发送消息。形式很简单,我想保持这种方式。如果我不想使用任何验证码,保护联系表单免受垃圾邮件和机器人攻击的最佳方法是什么?

Your message:...
Your e-mail:...
[Send]

最佳答案

您可以使用表单键技术保护您的表单:

  1. 在向用户显示表单时,仅为该单个表单提交生成一个随机 ID(“表单 key ”)。将表单 key 存储在 session 变量中。在隐藏的输入字段中提交“表单 key ”。
  2. 在服务器端,根据 session 变量中存储的 key 检查提交的表单 key 。使用后立即作废。 (从 session 中删除它)

如果没有验证码或类似的东西,就不可能真正保护表单免受滥用。

但是,恶意垃圾邮件发送者必须使用此技术

  1. 通过 HTTP 为每个表单提交请求表单以获得有效的唯一 forkey
  2. 解析DOM树/HTML代码获取表单键
  3. 以正确的格式提交

此技术还可以保护您的表单免受多次意外提交的影响。

这是一个代码示例:

<?php
session_start();
if (isset($_POST['form_submit'])) {
  // do stuff
  if (isset($_POST['formkey']) && isset($_SESSION['formkeys'][$_POST['formkey']])) {
    echo "valid, doing stuff now ... "; flush();
    // delete formkey from session
    unset($_SESSION['formkeys'][$_POST['formkey']]);
    // release session early - after committing the session data is read-only
    session_write_close();
    // do whatever you like with the form data here
    send_contact_mail($_POST);
  }
  else {
    echo "request invalid or timed out.";
  }
}
else {
  // show form with formkey
  $formkey = md5("foo".microtime().rand(1,999999));
  // put current formkey into list of valid form keys for the user session
  if (!is_array($_SESSION['formkeys']) {
    $_SESSION['formkeys'] = array();
  ]
  $_SESSION['formkeys'][$formkey] = now();
?>
<html>
<head><title>form key</title></head>
<body>
  <form method="POST">
    <input type="hidden" name="PHPSESSID" value="<?=session_id()?>">
    <input type="text" name="formkey" 
      value="<?= $formkey ?>">
    <input type="submit" name="form_submit" value="Contact us!">
  </form>
</body>
</html>
<?php } ?>

关于php - 如何在没有验证码的情况下保护联系表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9516540/

相关文章:

php - 如何将 woocommerce 订单号更新到自定义 ACF 字段? (wordpress)

php - PHP 5.x 中是否有任何简单的方法可以在 RecordSet 上回显任何类型的数据?

html - Bootstrap 表单布局(桌面与移动输入顺序)

PHP 准备的 MySQL UPDATE 语句在字符串中包含变量

PHP-PDO-Mysql : Can't execute two requests in the same page

php - 需要帮助在 Laravel 3 中编写频繁查询

php - 如何上传带有其他详细信息(如用户名、电子邮件、手机等)的照片

php - 如何将不同的表单数据发送到php文件以保存在数据库中

javascript - 表单提交字段为空白。使用 Javascript 隐藏和显示字段

javascript - 在 document.forms[x].elements 中从 DOM 中省略图像输入是否正常?