【发布时间】:2019-07-03 11:26:56
【问题描述】:
几天来,我正在将验证码实施到我的联系表单中。我经历了多个教程和 stackoverflow 讨论,但似乎我仍然做错了什么(我对 PHP 还不是很有经验,所以可能我错过了一些东西)。
a) 我的联系表工作正常(发送电子邮件、检查空白字段等)
b) 验证码显示正确
c) Captcha 验证不工作
对于联系表单,我使用 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 知识又是失败的测试的一天。
谢谢!
【问题讨论】:
-
你为什么不用谷歌的reCaptcha?
-
在比较它们之前先做一个
var_dump($_POST['captcha_challenge']);和var_dump($_SESSION['captcha_text']);,看看它们包含什么。 -
send-email.php文件存在语法错误 -
@MilanG 没有帮助。除了进行重新验证可能需要很长时间(有时点击 10 到 20 秒)这一事实之外,并不是每个人都愿意使用 3rd 方解决方案或强迫他们的客户训练 Google 的机器学习算法。