簡體   English   中英

PHP Mailer 6 Contact Form 發送消息和附件,但 reCaptcha V2 被忽略

[英]PHP Mailer 6 Contact Form sends message and attachments, but reCaptcha V2 is ignored

我希望我能自己解決這個問題,但我沒有嘗試過。

我已經設法使用 PHPMailer 拼湊了一個聯系表格,並可以選擇添加多個完美的附件。

但是,當我嘗試添加 reCaptcha V2 時,它會被完全忽略,並且無論是否勾選 Captcha,都會提交聯系表單。

我嘗試了許多在線發布的不同方法,但這些方法根本無法提交表單。

有人可以告訴我哪里出錯了:

表單的 HTML 部分:

<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">

<title>Contact Us:</title>

<link rel="canonical" href="" />
<link rel="stylesheet" type="text/css" href="css/normalise.css" />
<link rel="stylesheet" type="text/css" href="css/style.css" />

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
</head>

<body>

  <div class="contact_form_container">
    All fields marked with <span class="required">*</span> are required
    <form id="form" action="mail-script.php" method="post" enctype="multipart/form-data">
    
    <div class="elem-group">
      <label class="form_label">Name <span class="required">*</span></label>
      <input class="form-control form-control-name form_field" type="text" name="name" required>
    </div>
    
    <div class="elem-group">
      <label class="form_label">Company</label>
      <input class="form-control form-control-subject form_field" type="text" name="company">
    </div>
    
    <div class="elem-group">
      <label class="form_label">Email Address <span class="required">*</span></label>
      <input class="form-control form-control-email form_field" type="email" name="email" required>
    </div>
    
    <div class="elem-group">
      <label class="form_label">Phone Number</label>
      <input class="form-control form-control-phone form_field" type="tel" name="phone" pattern="\d*">
    </div>
    
    <div class="elem-group">
      <label class="form_label">Message <span class="required">*</span></label>
      <textarea name="message" rows="7" required class="form-control form-control-message form_field">
      </textarea>
    </div>
    
    <div class="elem-group">
      <label class="form_label">Upload Your Files</label> 
      <input type="file" name="attachment[]" class="form-control" multiple>
    </div>
      
    <div class="elem-group">
      <label class="form_label">&nbsp;</label>
      <div class="g-recaptcha" data-sitekey="xxxxxx"></div>    
    </div>                         
    
    <div class="elem-group">
      <label class="form_label cft">&nbsp;</label>
      <button class="btn-primary button" type="submit" value="Send" name="submit" >Send Message</button>
    </div>

    </form>
  </div>
      
</body>
</html>

PHP

<?php

use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;

require './src/Exception.php';
require './src/PHPMailer.php';
require './src/SMTP.php';

class CaptchaTest
{
  private $captchaSecretKey = 'XXX';

  //call this function and pass in the response value from the form in order to get Google to test the captcha. Will return true or false.
  public function testCaptchaResponse($captchaResponse)
  {
    //generate URL as per Google's documentation
    $createGoogleUrl = 'https://www.google.com/recaptcha/api/siteverify?secret='.urlencode($this->captchaSecretKey).'&response='.urlencode($captchaResponse);
    //send request to Google and get back the raw JSON response.
    $verifyRecaptcha = $this->sendHttpRequest($createGoogleUrl);
    //decode the JSON into a PHP array so we can examine individual data items within it
    $decodeGoogleResponse = json_decode($verifyRecaptcha,true);

    //examine the response from Google and return true/false accordingly.
    if($decodeGoogleResponse['success'] == 1) return true;
    else return false;
  }
  
  //send a HTTP request to the specified URL using cURL
  private function sendHttpRequest($url)
  {
    $ch = curl_init();
    $getUrl = $url;
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
    curl_setopt($ch, CURLOPT_URL, $getUrl);
    curl_setopt($ch, CURLOPT_TIMEOUT, 80);
    
    $response = curl_exec($ch);
    curl_close($ch);
    return $response;
  }
}


//check form button and captcha field were submitted
if(isset($_POST['submit'], $_POST['g-recaptcha-response'])) {

    //test the captcha
    $cTest = new CaptchaTest();
    $captchaResult = $cTest->testCaptchaResponse($_POST['g-recaptcha-response']); }

    if ($captchaResult == true) {

        $mail = new PHPMailer(true);
        $mail->SMTPDebug = 0;
        $mail->Host = 'in-v3.mailjet.com';
        $mail->SMTPAuth = true;
        $mail->Username = 'XXX';
        $mail->Password = 'XXX';
        $mail->SMTPSecure = 'tls';
        $mail->Port = 587;
        $mail->setFrom($_POST['email'], $_POST['name']);
        $mail->addAddress('XXX@XXX.co.uk');
        $mail->addReplyTo($_POST['email'], $_POST['name']);
        

        //Attach multiple files one by one
        for ($ct = 0; $ct < count($_FILES['userfile']['tmp_name']); $ct++) {
          $uploadfile = tempnam(sys_get_temp_dir(), hash('sha256', $_FILES['userfile']['name'][$ct]));
          $filename = $_FILES['userfile']['name'][$ct];
    
          if (move_uploaded_file($_FILES['userfile']['tmp_name'][$ct], $uploadfile)) {
            $mail->addAttachment($uploadfile, $filename);
          } 
        }

        $mail->isHTML(true);
        $mail->Subject = 'Website Enquiry';
        $mail->Body = "<p>You received an enquiry from:</p>
          <b>Name:</b>  $_POST[name]<br><br>
          <b>Company:</b>  $_POST[company]<br><br>
          <b>Phone Number:</b>  $_POST[phone]<br><br>
          <b>E-Mail:</b> $_POST[email]<br><br>
          <b>Message:</b> $_POST[message]";
          
        try {
             $mail->send();
header('Location: thank.html');
exit('Redirecting you to thank.html');
        } catch (Exception $e) {
            echo "Your message could not be sent! PHPMailer Error: {$mail->ErrorInfo}";
        }
    } 
    else
    {
        echo "Captcha failed, please try again";
    }
    
?>

提前致謝

目前,您的 PHP 代碼根本不測試驗證碼值。 根據 Google 的文檔,您需要將提交的驗證碼值(在表單的 POST 數據中提供)發送到 Google 的服務器,以便他們對其進行驗證,並就用戶是否通過測試給出是/否響應。 一旦知道這一點,您就可以決定是否繼續發送電子郵件。

我建議將此功能封裝到一個小類中,然后您可以從主代碼流中調用該類來執行檢查。 像這樣的東西:

class ReCaptchaTest
{
  private $captchaSecretKey = 'XXXXXXXXX';

  //call this function and pass in the response value from the form in order to get Google to test the captcha. Will return true or false.
  public function testCaptchaResponse($captchaResponse)
  {
    //generate URL as per Google's documentation
    $createGoogleUrl = 'https://www.google.com/recaptcha/api/siteverify?secret='.urlencode($this->captchaSecretKey).'&response='.urlencode($captchaResponse);
    //send request to Google and get back the raw JSON response.
    $verifyRecaptcha = $this->sendHttpRequest($createGoogleUrl);
    //decode the JSON into a PHP array so we can examine individual data items within it
    $decodeGoogleResponse = json_decode($verifyRecaptcha,true);

    //examine the response from Google and return true/false accordingly.
    if($decodeGoogleResponse['success'] == 1) return true;
    else return false;
  }
  
  //send a HTTP request to the specified URL using cURL
  private function sendHttpRequest($url)
  {
    $ch = curl_init();
    $getUrl = $url;
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
    curl_setopt($ch, CURLOPT_URL, $getUrl);
    curl_setopt($ch, CURLOPT_TIMEOUT, 80);
    
    $response = curl_exec($ch);
    curl_close($ch);
    return $response;
  }
}

然后在您的主代碼中,首先檢查驗證碼值是否已確定提交,然后在嘗試對電子郵件執行任何操作之前運行檢查:

//check form button and captcha field were submitted
if(isset($_POST['submit'], $_POST['g-recaptcha-response'])) {

  //test the captcha
  $cTest = new CaptchaTest();
  $captchaResult = $cTest->testCaptchaResponse($_POST['g-recaptcha-response']);

  if ($captchResult == true) {
    // go ahead with all your email code here
  }
  else
  {
    echo "Captcha failed, please try again";
}
else
{
  echo "Please submit the form with all required fields";
}

歸功於本教程的靈感。 使此代碼正常工作還取決於您完成 Google 開發人員帳戶中的所有設置步驟,以便使用 reCaptcha 注冊您的網站(如教程中所示)。

@ADyson 我按照您的建議做了,並在有機會時詳細查看了錯誤。 問題只是證明是“$captchaResult”中缺少“a”。

非常感謝你讓我走到這一步,我非常感謝你的努力和建議,因為我自己不可能做到這一點。

如果它對其他人有幫助,那么工作的 PHP 代碼如下(我還設法標記了在不勾選 reCaptacha 的情況下提交表單的功能會在彈出框中拋出錯誤消息,然后將您發送回完成表格再試一次):

'''

<?php

    use PHPMailer\PHPMailer\PHPMailer;
    use PHPMailer\PHPMailer\Exception;

    require './src/Exception.php';
    require './src/PHPMailer.php';
    require './src/SMTP.php';

class CaptchaTest
{
  private $captchaSecretKey = 'XXXXX';

  //call this function and pass in the response value from the form in order to get Google to test the captcha. Will return true or false.
  public function testCaptchaResponse($captchaResponse)
  {
    //generate URL as per Google's documentation
    $createGoogleUrl = 'https://www.google.com/recaptcha/api/siteverify?secret='.urlencode($this->captchaSecretKey).'&response='.urlencode($captchaResponse);
    //send request to Google and get back the raw JSON response.
    $verifyRecaptcha = $this->sendHttpRequest($createGoogleUrl);
    //decode the JSON into a PHP array so we can examine individual data items within it
    $decodeGoogleResponse = json_decode($verifyRecaptcha,true);

    //examine the response from Google and return true/false accordingly.
    if($decodeGoogleResponse['success'] == 1) return true;
    else return false;
  }
  
  //send a HTTP request to the specified URL using cURL
  private function sendHttpRequest($url)
  {
    $ch = curl_init();
    $getUrl = $url;
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
    curl_setopt($ch, CURLOPT_URL, $getUrl);
    curl_setopt($ch, CURLOPT_TIMEOUT, 80);
    
    $response = curl_exec($ch);
    curl_close($ch);
    return $response;
  }
}


//check form button and captcha field were submitted
if(isset($_POST['submit'], $_POST['g-recaptcha-response'])) {

  //test the captcha
  $cTest = new CaptchaTest();
  $captchaResult = $cTest->testCaptchaResponse($_POST['g-recaptcha-response']); }

  if ($captchaResult == true) {

        $mail = new PHPMailer(true);
        $mail->SMTPDebug = 0;
        $mail->Host = 'in-v3.mailjet.com';
        $mail->SMTPAuth = true;
        $mail->Username = 'XXXXX';
        $mail->Password = 'XXXXX';
        $mail->SMTPSecure = 'tls';
        $mail->Port = 587;
        $mail->setFrom($_POST['email'], $_POST['name']);
        $mail->addAddress('XXXXX');
        $mail->addReplyTo($_POST['email'], $_POST['name']);
        

//Attach multiple files one by one
    for ($ct = 0; $ct < count($_FILES['userfile']['tmp_name']); $ct++) {
     $uploadfile = tempnam(sys_get_temp_dir(), hash('sha256', $_FILES['userfile']['name'][$ct]));
     $filename = $_FILES['userfile']['name'][$ct];
       if (move_uploaded_file($_FILES['userfile']['tmp_name'][$ct], $uploadfile)) {
          $mail->addAttachment($uploadfile, $filename);
        } }

        $mail->isHTML(true);
        $mail->Subject = 'Website Enquiry';
        $mail->Body = "<p>You received an enquiry from:</p>
    <b>Name:</b>  $_POST[name]<br><br>
    <b>Company:</b>  $_POST[company]<br><br>
    <b>Phone Number:</b>  $_POST[phone]<br><br>
    <b>E-Mail:</b> $_POST[email]<br><br>
    <b>Message:</b> $_POST[message]";
            
  
        try {
             $mail->send();
header('Location: thank.html');
exit('Redirecting you to thank.html');
        } catch (Exception $e) {
            echo "Your message could not be sent! PHPMailer Error: {$mail->ErrorInfo}";
        }
        
    } 
    
else
  {
    

    echo "<script>
          alert('Captcha Error!, returning you to the Contact page')
          history.back()
          </script>";
}

    
?>

'''

抱歉,如果最終代碼沒有達到應有的優雅水平,我在 PHP 方面仍處於亞虛擬水平......

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM