Captcha系统在PHP,AJAX联系表格

时间:2015-08-13 14:57:09

标签: javascript php jquery ajax captcha

2011年,我从codecanyon购买了一个PHP联系表单,该表单使用AJAX来处理表单。在今天向他们报告我的问题之后,他们回应说他们不再为他们的老人提供支持。产品(他们通常提供的终身支持通常都是如此)......所以他们不会帮助我,所以这篇帖子就这样了。

我会说这不是正常的问题,但我认为它很重要 - 它在这里得到了解决 - 这是(这是我向卖家发送的电子邮件,但确实解释了问题):

=================

我的AJAX联系表格有一个不寻常的问题(您需要仔细阅读并慢慢阅读)。

好吧一切正常100%但是......让我解释一下(基本上这与Captcha和验证有关)

我的网站在每个页面上都有许多页面,其中包含您的在线表单。 现在我还有一个列表页面,其中包含指向带有表单的所有页面的链接。

示例:

让我们说我在一个列表页面(一个包含大量链接的页面转到其他页面),然后我右键单击链接A在新标签页中打开页面A然后我也右键单击链接B以在新选项卡中打开页面B.是的,所以我们有一个列表页面(在我面前仍然打开)以及在新标签页面中打开的另外两个页面(页面A和页面B)......如上所述,这两个页面都有你的在线表格。

现在,我填写两个表格并点击提交。

我在新标签页面中右键点击打开的第一页(页面A) - 即使我已经正确验证了该表格,该表单的Captcha也不起作用...但是表格&第39页上的Captcha确实有效(就像它应该的那样)。为什么页面A上的Captcha(我打开的第一页)不起作用?

我感觉在整个验证系统中,因为页面B已经打开最后,验证会将该页面的验证码考虑在内,使用验证码进行验证(整个会话在我的网站上冲浪)从而使第一个打开的页面(页面A)上的Captcha不起作用。

所以我做了一个实验:

我重新启动并再次执行相同的操作,IE:我右键单击链接A在新选项卡中打开页面A ...然后我也右键单击链接B在新选项卡中打开页面B.

我在Page A的验证码验证字段中填写了Page B的验证码,您知道什么 - 这是一场比赛!

所以这是我的问题因为我知道有些人上网时(我一直这样做,也许你也这样做),他们喜欢右键点击链接在新标签中打开它们以便他们可以回复稍后浏览列表页面。因此,此人可能在浏览器中打开了6个选项卡,每个页面都有您的在线表单。如果用户想要提交每个表单,那么他/她将会遇到我上面报告的确切问题。他们将能够通过1个表单(在新标签中打开的最后页面)发送,但除非他们刷新页面,否则其他页面的Captchas将无法正常工作。但是大多数人都不会想到这样做 - 相反,他们会认为我的网站有些不对劲 - 我很害怕。

有解决方案吗? 我甚至不确定你以前是否注意到了这一点?

我希望我已经清楚地解释了这个情况,如果你能提供帮助,我真的很感激。

=================

现在回到你身边。造成这种情况的原因是什么?

表单需要工作/处理等3个文件(我不包括此帖子中的CSS文件而不是表单的html,因为我认为不是必要的)。

1)process.php

2)image.php(这是验证码)

3)ajax.js

PROCESS.PHP

<?php if (!isset($_SESSION)) session_start();

if(!$_POST) exit;

if (!defined("PHP_EOL")) define("PHP_EOL", "\r\n");

$address = "email@example.com";
$bcc = "email@example.com";

$name    = $_POST['name'];
$email  = $_POST['email'];
$phone  = $_POST['phone'];
$comments = $_POST['comments'];

if (isset($_POST['verify'])) :
    $posted_verify   = $_POST['verify'];
    $posted_verify   = md5($posted_verify);
else :
    $posted_verify = '';
endif;


$session_verify = $_SESSION['verify'];

if (empty($session_verify)) $session_verify = $_COOKIE['verify'];

$error = '';

    if(trim($name) == '') {
        $error .= '<li>Your name is required.</li>';
    }

    if(trim($email) == '') {
        $error .= '<li>Your e-mail address is required.</li>';
    } elseif(!isEmail($email)) {
        $error .= '<li>You have entered an invalid e-mail  
  address.</li>';
    }

    if(trim($phone) == '') {
        $error .= '<li>Your phone number is required.</li>';
    } elseif(!is_numeric($phone)) {
        $error .= '<li>Your phone number can only contain digits 
 (numbers and no spaces).</li>';
    }

    if(trim($comments) == '') {
        $error .= '<li>You must enter a message to send.</li>';
    }

    if($session_verify != $posted_verify) {
        $error .= '<li>The verification code you entered is 
 incorrect.</li>';
    }

    if($error != '') {
        echo '<div class="error_title"><h6><span>Attention!
</span> Please correct the errors below and try again</h6>';
        echo '<ul class="error_messages">' . $error . '</ul>';
        echo '<div class="close"></div>';
        echo '</div>';

    } else {

    if(get_magic_quotes_gpc()) { $comments = stripslashes($comments); }


     $e_subject = 'Booking / Enquiry';


     $msg = '<html>
<body style="margin:0; padding:0;">

Name: '.$_POST['name'].'
Email: '.$_POST['email'].'
Contact Number:  '.$_POST['phone'].'
Notes: '.$_POST['comments'].'


 </body>
 </html>';



    $msg = wordwrap( $msg, 70 );

    $headers = "From: $email\r\nBCC:{$bcc}\r\n" . PHP_EOL;
    $headers .= "Reply-To: $email" . PHP_EOL;
    $headers .= "MIME-Version: 1.0" . PHP_EOL;
    $headers .= "Content-type: text/html; charset=utf-8" .     PHP_EOL;
    $headers .= 'Content-Transfer-Encoding: 8bit'. "\n\r\n" .  PHP_EOL;

    if(mail($address, $e_subject, $msg, $headers)) {


     echo "<div class='success'>";
     echo "<h6>Your Enquiry has been Successfully submitted.  </h6>";
     echo '<div class="close"></div>';
     echo "</div>";


     } else {

     echo 'ERROR!'; 

     }

   }

    ?>

*请注意,在上面的process.php代码中,我删除了一个似乎验证电子邮件地址字段的函数 - 我没有在上面的代码中包含它的原因是因为代码很重(会占用很多空间)而且我认为没有必要包括

IMAGE.PHP

<?php if (!isset($_SESSION)) session_start(); header("(anti-spam-
content-
type:) image/png");

$enc_num = rand(0, 9999);
$key_num = rand(0, 24);
$hash_string = substr(md5($enc_num), $key_num, 5); // Length of 
String
$hash_md5 = md5($hash_string);

 $_SESSION['verify'] = $hash_md5;


 setcookie("verify", $hash_md5, time()+3600, "/");

 session_write_close();



 $bgs = array("../../img/1.png","../../img/2.png","../../img/3.png");
 $background = array_rand($bgs, 1);


 $img_handle = imagecreatefrompng($bgs[$background]);
 $text_colour = imagecolorallocate($img_handle, 108, 127, 6);
 $font_size = 5;

 $size_array = getimagesize($bgs[$background]);
 $img_w = $size_array[0];
 $img_h = $size_array[1];

 $horiz = round(($img_w/2)-
 ((strlen($hash_string)*imagefontwidth(5))/2), 
 1);
  $vert = round(($img_h/2)-(imagefontheight($font_size)/2));



 imagestring($img_handle, $font_size, $horiz, $vert, $hash_string, 
 $text_colour);
 imagepng($img_handle);


 imagedestroy($img_handle);

 ?>

AJAX.JS

   jQuery(document).ready(function() {
   $('.advertform').submit(function() {
    var action = $(this).attr('action');
    var form = this;
    $('.submit', this).attr('disabled', 'disabled').after(
          '<div class="loader"></div>').addClass("active");
    $('.message', this).slideUp(750, function() {
        $(this).hide();
        $.post(action, {
            name: $('.name', form).val(),
            email: $('.email', form).val(),
            phone: $('.phone', form).val(),
            comments: $('.comments', form).val(),
            verify: $('.verify', form).val()
        },
        function(data) {
            $('.message', form).html(data);
            $('.message', form).slideDown('slow');
            $('.loader', form).fadeOut('fast', function() {
                $(this).remove();
            });
            $('.submit', 
   form).removeAttr('disabled').removeClass("active");
        });
    });
    return false;
   });

   $('.message').on('click', function(){
    $('.message').slideUp();
   });

   });

查看上面的代码,有人能发现可能导致此问题的原因吗?我假设这可能与javascript有关吗?

1 个答案:

答案 0 :(得分:1)

我有个主意。将验证码值存储在一个数组中,并保留一个计数器;两者都存储在SESSION变量中。

因此,在表单中放入一个隐藏的输入,并将其设置为索引。

当我们检查验证码时,我们将$ _SESSION [&#39; captcha&#39;] [$ index]与$ _POST [&#39;验证码&#39;]进行比较。

任何时候你(客户)打开一个新窗口; $ index增加了。 我们通过url将该索引传递给image.php;例如src =&#34; img.php?index = 2&#34;

这是一个概念;完成此任务的最小代码。 用这个页面打开几个窗口。看看会发生什么

img.php

<?php 
session_start(); 
header("(anti-spam-content-type:) image/png");

$captcha_text = rand(0, 99999);
// we read a "index" from the URL, example: <img src="img.php?index=2">
$index = isset($_GET['index']) ? (int) $_GET['index'] : 0;

if( empty($_SESSION['captcha'])) {
  $_SESSION['captcha'] = array();
}
$_SESSION['captcha'][$index] = $captcha_text;

// @see http://php.net/manual/en/function.imagestring.php , first example
$im = imagecreate(100, 30);
$bg = imagecolorallocate($im, 55, 255, 255);
$textcolor = imagecolorallocate($im, 0, 0, 255);
imagestring($im, 5, 0, 0, $captcha_text, $textcolor);
header('Content-type: image/png');
imagepng($im);
imagedestroy($im);
?>

的index.php

<?php
session_start(); 
// we handle the POST
if ($_SERVER['REQUEST_METHOD'] === 'POST' && !empty($_SESSION['captcha'])) {
    if ($_SESSION['captcha'][ $_POST['index'] ] == $_POST['captcha']) {
      echo '<h2>correct</h2>';
    }
    else {
      echo '<h2>not correct</h2>';
    }
    echo '<a href="index.php">Back to form</form>';
    // header('location: index.php');
    exit;
}

// normal page, with form
if(isset($_SESSION['captcha_index'])) {// index
  // set a new index  
  $_SESSION['captcha_index']++;
}
else {
  $_SESSION['captcha_index'] = 0;
}
$captcha_index = $_SESSION['captcha_index']; 

echo '
<img src="img.php?index=' . $captcha_index . '">
<form action="" method="post">
  <input name="captcha">
  <input name="index" type="hidden" value="' . $captcha_index . '">
  <input type="submit" value="GO">
</form>
'; 

// we show what's happening.  Obviously you don't want to print this after test phase
$captcha = isset($_SESSION['captcha']) ? $_SESSION['captcha'] : array();
echo '
<br>print_r of $_SESSION[captcha] 
<pre>' . print_r($captcha, true) . '<pre>
';
?>