PHP HTML联系人表单中的验证码验证

时间:2019-07-03 11:26:56

标签: php html

几天来,我正在努力将人机验证(Captcha)实施到我的联系表中。我经历了多个教程和stackoverflow讨论,但似乎我仍然做错了什么(我对PHP的经验还不是很丰富,所以我可能会错过一些东西)。

a)我的联系表工作正常(发送电子邮件,检查空白字段等)

b)验证码显示正确

c)验证码验证有效

对于联系表格,我使用3个文件-.html文件-包含网页和两个.php文件(用于创建验证码的captcha.php,用于发送电子邮件和验证的send-email.php)。

1)kontakt.html:

<!DOCTYPE html><html lang="de">
<head>...</head>
<body>
<div class="contact-form-container">
                            <form  class="contact-form" action="php/send-email.php"  method="post" novalidate>
                                <div class="row">
                                    <div class="column width-6">
                                        <input type="text" name="fname" class="form-fname form-element large" placeholder="Firma*" tabindex="1" required>
                                </div>
                                <div class="column width-6">
                                    <input type="text" name="lname" class="form-lname form-element large" placeholder="Ihr Name*" tabindex="2" required>
                                    </div>
                                    <div class="column width-6">
                                        <input type="email" name="email" class="form-email form-element large" placeholder="E-Mail Adresse*" tabindex="3" required>
                                    </div>
                                     <div class="column width-6">
                                        <input type="tel" name="telefonnummer" class="form-website form-element large" placeholder="Telefonnummer*" tabindex="4" required>
                                    </div> 
                                </div>
                                <div class="row">
                                    <div class="column width-12">
                                        <div class="field-wrapper">
                                            <textarea name="message" class="form-message form-element large" placeholder="Nachricht*" tabindex="7" required></textarea>
                                        </div>
                                    </div>
                                     <div class="column width-6">
                                        <input type="text" name="honeypot" class="form-honeypot form-element large">
                                    </div>           
                                       <div class="elem-group column width-12">
                                           <label for="captcha">Captcha</label>
                                           <img src="php/captcha.php" alt="CAPTCHA" class="captcha-image"><i class="form fas fa-redo refresh-captcha"></i>
                                           <br><br>
                                           <input class="form-message form-element" type="text" id="captcha" name="captcha_challenge" pattern="[A-Z]{6}">                   
                                       </div>
                                    <div class="column width-12">                                           
                                           <input  type="submit" value="Senden" class="form-submit button medium bkg-theme bkg-hover-theme color-white color-hover-white">
                                    </div>              
                                </div>
                            </form>
                            <div class="form-response center"></div>           
                        </div>
</body> 
</html>

2)captcha.php(据我所知,可以生成验证码图像)

<?php

session_start();

$permitted_chars = 'ABCDEFGHJKLMNPQRSTUVWXYZ';

function generate_string($input, $strength = 10) {
    $input_length = strlen($input);
    $random_string = '';
    for($i = 0; $i < $strength; $i++) {
        $random_character = $input[mt_rand(0, $input_length - 1)];
        $random_string .= $random_character;
    }

    return $random_string;
}

$image = imagecreatetruecolor(200, 50);

imageantialias($image, true);

$colors = [];

$red = rand(125, 175);
$green = rand(125, 175);
$blue = rand(125, 175);

for($i = 0; $i < 5; $i++) {
  $colors[] = imagecolorallocate($image, $red - 20*$i, $green - 20*$i, $blue - 20*$i);
}

imagefill($image, 0, 0, $colors[0]);

for($i = 0; $i < 10; $i++) {
  imagesetthickness($image, rand(2, 10));
  $line_color = $colors[rand(1, 4)];
  imagerectangle($image, rand(-10, 190), rand(-10, 10), rand(-10, 190), rand(40, 60), $line_color);
}

$black = imagecolorallocate($image, 0, 0, 0);
$white = imagecolorallocate($image, 255, 255, 255);
$textcolors = [$black, $white];

$font = 'arial.ttf';

$string_length = 6;
$captcha_string = generate_string($permitted_chars, $string_length);

$_SESSION['captcha_text'] = $captcha_string;

for($i = 0; $i < $string_length; $i++) {
  $letter_space = 170/$string_length;
  $initial = 15;

  imagettftext($image, 24, rand(-15, 15), $initial + $i*$letter_space, rand(25, 45), $textcolors[rand(0, 1)], $font, $captcha_string[$i]);
}

header('Content-type: image/png');
imagepng($image);
imagedestroy($image);
?>

3)send-email.php(发送电子邮件并进行验证)

<?php
// Your Email
    $recipient = "mymail"; 


    // Check $recipient
    if($recipient === '') {
        returnAndExitAjaxResponse(
            constructAjaxResponseArray(
                FALSE,
                'RECIPIENT_IS_NOT_SET',
                array('error_message'=> 'RECIPIENT email address is not set. Please configure the script.')
            )
        );
    }

if ($_POST['captcha_challenge'] == $_SESSION['captcha_text']) {


    // Check for empty required field
    if(!isset($_POST["email"]) || !isset($_POST["fname"]) || !isset($_POST["message"])) {
        returnAndExitAjaxResponse(
            constructAjaxResponseArray(
                FALSE,
                'MISSING_REQUIRED_FIELDS',
                array('error_message'=> 'MISSING_REQUIRED_FIELDS should not be occurred.')
            )
        );
    }

    // Sanitize input
    $fname  = filter_var($_POST["fname"], FILTER_SANITIZE_STRING);
    $lname  = filter_var($_POST["lname"], FILTER_SANITIZE_EMAIL);
    $email = filter_var(trim($_POST["email"]), FILTER_SANITIZE_EMAIL);
    $message = filter_var($_POST["message"], FILTER_SANITIZE_STRING, FILTER_FLAG_NO_ENCODE_QUOTES);


    // Headers
    $headers = 'From: '.$fname.' <'.$email.'>' . "\r\n";
    $headers .= 'Reply-To: '.$email.'' . "\r\n";
    $headers .= 'X-Mailer: PHP/' . phpversion();

    // Subject
    $subject = "Neue E-Mail von Kontakt Formular";

    // Build Message
    $email_content = "Firma: $fname\n";
    $email_content .= "Ihr Name: $lname\n";
    $email_content .= "Telefon nummer: $telefonnummer\n"; 
    $email_content .= "Email: $email\n\n";
    $email_content .= "Nachricht:\n$message\n\n\n";
    $email_content .= "CLIENT IP:\n".get_client_ip()."\n";
    $email_content .= "HOST IP:\n".$_SERVER['SERVER_ADDR']."\n";

else {
    } echo '<p>Captcha verification is wrong. Take other action.</p>';

}


// Check if sent
try {
    $sendmailResult = mail($recipient, $subject, $email_content, $headers);
    if( $sendmailResult === TRUE ) {
        returnAndExitAjaxResponse(
            constructAjaxResponseArray(
                TRUE
            )
        );
    } else {
        returnAndExitAjaxResponse(
            constructAjaxResponseArray(
                FALSE,
                'ERROR_AT_PHPMAIL',
                array('error_information'=> error_get_last() )
            )
        );
    }
} catch (Exception $_e) {
    returnAndExitAjaxResponse(
        constructAjaxResponseArray(
            TRUE,
            'ERROR_AT_PHPMAIL',
            array('error_message'=> $_e->getMessage())
        )
    );
}


function constructAjaxResponseArray ($_response, $_message = '', $_json = null) {
    $_responseArray = array();
    $_response = ( $_response === TRUE ) ? TRUE : FALSE;
    $_responseArray['response'] = $_response;
    if(isset($_message)) $_responseArray['message'] = $_message;
    if(isset($_json)) $_responseArray['json'] = $_json;

    return $_responseArray;
}

function returnAndExitAjaxResponse ($_ajaxResponse) {
    if(!$_ajaxResponse){
        $_ajaxResponse = array('response'=>false,'message'=>'Unknown error occurred.');
    }
    header("Content-Type: application/json; charset=utf-8");
    echo json_encode($_ajaxResponse);
    die();
}


// Function to get the client IP address
function get_client_ip() {
    $ipaddress = '';
    if (isset($_SERVER['HTTP_CLIENT_IP'])) {
        $ipaddress = $_SERVER['HTTP_CLIENT_IP'];
    } else if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
        $ipaddress = $_SERVER['HTTP_X_FORWARDED_FOR'];
    } else if(isset($_SERVER['HTTP_X_FORWARDED'])) {
        $ipaddress = $_SERVER['HTTP_X_FORWARDED'];
    } else if(isset($_SERVER['HTTP_FORWARDED_FOR'])) {
        $ipaddress = $_SERVER['HTTP_FORWARDED_FOR'];
    } else if(isset($_SERVER['HTTP_FORWARDED'])) {
        $ipaddress = $_SERVER['HTTP_FORWARDED'];
    } else if(isset($_SERVER['REMOTE_ADDR'])) {
        $ipaddress = $_SERVER['REMOTE_ADDR'];
    } else {
        $ipaddress = 'UNKNOWN';
    }
    return $ipaddress;
}

现在,如果我将验证码字段保留为空,那么电子邮件将从联系表单发送到邮件电子邮件地址。但是,如果我在captcha_challenge字段中输入了任何内容(无论是否正确),则联系表单在提交后会冻结,并且不会发送电子邮件。

我认为出错的原因是send-email.php代码的这一部分(尽管如此,我不知道如何解决它):

if ($_POST['captcha_challenge'] == $_SESSION['captcha_text']) { 
//code 
else {
        } echo '<p>Captcha verification is wrong. Take other action.</p>';

    }

我尝试了许多不同的方法来验证此验证码或使用其他许多验证码提示。现在由于我有限的php知识,第二天失败了,我对此一无所知。

谢谢!

2 个答案:

答案 0 :(得分:1)

您在send-email.php上缺少session_start();

答案 1 :(得分:0)

我要在此处粘贴captcha.php

 <?php
$post = [
   'secret' => '6LfcOEcUAAAAABldSkevRJL75VSrvheVbc_4z9wU', //Enter the secret key provided by the google (just copy and paste it)
   'response' => $_POST['googleResponse'],

];
$ch = curl_init();
echo 
curl_setopt($ch, CURLOPT_URL, 'https://www.google.com/recaptcha/api/siteverify');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post));
$response = curl_exec($ch);
var_export ($response);
// echo $response;
?>

此处的captcha.js

////////   GOOGLE RECAPTCHA CLIENT SIDE AND SERVER SIDE VERIFICATION   /////////////

            //----------------------------------------------------/
           // onloadCallback()
          // this 
         //----------------------------------------------------/




 var onloadCallback = function() {
        grecaptcha.render('html_element', {    // oncallback render a div with id html_element
          'sitekey' : '6LfcOEcUAAAAAAia1cMp60bnm1PMaFrmJ808il_D', // sitekey for the  captcha 
          'theme' : 'light',           // change the theme for light and dark
          'widgetId': 'widgetId',      // add widget id attribute which is optional
          callback(){
            console.log( 'another callback function here');

             response = grecaptcha.getResponse();    // get the value of response when user submits recaptcha
            console.log('response from google : ', response);

            // send post method to captcha php that is usin curl post request for cross domain
             $.post("captcha.php",
                    {
                      googleResponse: response     // pass the google response

                    },
                      function(response, status){   // pass two parameters respnse  and status 
                           console.log("response after ssv : ", response, status); 

                           if ( status == 'success'){
                             captchaSuccess = status;
                             captchares = captchaSuccess;
                            console.log("captchaSuccess :", captchaSuccess);


                           }
                           // alert response and the status here after verification from google 
                      });
            }
        });
    };

这是我的index.php

<!DOCTYPE html>
<html>
<head>
  <title>captcha</title>
  <link rel="stylesheet" type="text/css" href="">
</head>
<body>
<div id="html_element"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit"
        async defer>
    </script>
<script src="captcha.js"></script>
</body>
</html>

使用此代码段包含captchav2验证。您只需要将其包含在代码中,就可以开始使用了,它只包含与captchav2相关的代码,没有什么多余的。希望对您有帮助。