reCaptcha v2.0 + PHPMailer+Gmail+SMTP

reCaptcha v2.0

A PHPMailer + Gmail + SMTP és a Composer telepítésének a lépéseit itt találod meg.

reCaptcha letöltése és telepítése

Állj a site-od  gyökér könyvtárába és add ki az alábbi parancsot

composer require google/recaptcha

Ha eddig még nem jött létre, akkor létrejön a /vendor könyvtár, abban az autoload.php fájl és a vendor/google/recaptcha könyvtárban a megfelelő lib.

Innentől a kód:

<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;
use ReCaptcha\ReCaptcha;

$dir = realpath(dirname(__FILE__)."/..");

// Nyelvi beállítások, recaptcha és email tesztelés átvétele
$lang = "en";
session_start();
if( isset( $_SESSION["lang"] ) ){
    $lang = $_SESSION["lang"];
}

$test      = isset($_SESSION["test"]) ? $_SESSION["test"] : false;
$emailtest = isset($_SESSION["emailtest"]) ? $_SESSION["emailtest"] : false;

// require ReCaptcha osztály betöltése
require $dir."/vendor/autoload.php";

// PHPMailer nyelvi osztály betöltése
if($lang != "en"){
    require $dir."/vendor/phpmailer/phpmailer/language/phpmailer.lang-$lang.php";
}

// Language setting
if( $lang == "hu"){
    // an email address that will be in the From field of the email.
    $fromName    = "Teszt Űrlap";
    $sendToName  = "Teszt Tulajdonos";               
    $subject     = "Új üzenet a Teszt honlapról";
    // form field names and their translations.
    // array variable name => Text to appear in the email
    $fields = [
        'name'    => 'Keresztnév', 
        'surname' => 'Vezetéknév', 
        'phone'   => 'Telefon', 
        'email'   => 'Email', 
        'message' => 'Üzenet',
        'server'  => "Szerver"
    ];
        
    $okMessage = "Az üzenetet sikeresen elküldtük. Hamarosan válaszolunk!";
    $errorMessage = "Hiba történt az üzenet elküldése közben. Kérjük próbálja később újra vagy írjon az oldalon található email címre";
    $RecaptchaIsNotSet = "ReCaptcha nincsen beállítva";
    $RecaptchaWasNotValidated = "ReCaptcha nem volt érvényesítve.";        
    $emailText     = $subject."\n=============================\n";
    $emailTextHTML = "<h1>$subject</h1><hr/>";
    $mailerError = "Levelező program hiba: "; 
    $emailCoding = "UTF-8";           
}else{
    $fromName   = "Teszt Form";
    $sendToName = "Teszt Owner";
    $subject    = "New message from Teszt Form";

    $fields = [
        'name'    => 'Name',
        'surname' => 'Surname', 
        'phone'   => 'Phone', 
        'email'   => 'Email', 
        'message' => 'Message',
        "server"  => "Server"
    ];
        
    $okMessage = "Contact form successfully submitted. Thank you, I will get back to you soon!";
    $errorMessage = "There was an error while submitting the form. Please try again later or write an email to address on the page";
    $RecaptchaIsNotSet = "ReCaptcha is not set";
    $RecaptchaWasNotValidated = "ReCaptcha was not validated.";
    $emailText = $subject."\n=============================\n";
    $emailTextHTML = "<h1>$subject</h1><hr />";
    $mailerError = "Mailer Error: ";      
}

// if you are not debugging and don't need error reporting, turn this off by error_reporting(0);
$er = $test || $emailtest ? E_ALL & ~E_NOTICE : 0;
error_reporting($er);

try { 
    // Recaptcha: https://www.freecodecamp.org/news/build-a-bootstrap-form-with-recaptcha-and-php-backend-for-emails-in-30-minutes-17964a374819/   
    // validate the ReCaptcha, if something is wrong, we throw an Exception,
    // i.e. code stops executing and goes to catch() block    
    if (!isset($_POST['g-recaptcha-response'])) {
        throw new \Exception($RecaptchaIsNotSet);
    }   
    $g_recaptcha_response = $_POST['g-recaptcha-response'] ;    

    /* A kulcsok létrehozása https://www.google.com/recaptcha/admin
    * 
    * Test localhost-on: https://stackoverflow.com/questions/74047263/use-recaptcha-on-localhost
    *   Site key (Ez kerül az oldalra nyilvánosan): 6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI
    *   Secret Key (Ez a PHP kódban van titkosan) : 6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe
    *   Ne használd éles szerveren!
    * 
    * www.fzolee.hu szerveren
    *   Site Key  :   xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    *   Secret Key: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    *
    * Az éles szerveren (Ide a Google szerveren megadott kódot kell írni
    *   Site Key  :   ************************************************
    *   Secret Key: ************************************************
    */
    switch( $_SERVER["SERVER_NAME"] ){
        case "testoldal.local" :  // fejlesztői gép
        case "localhost" :
        case "127.0.0.1" :
        case "192.168.1.1" :
            $recaptchaSecret = "6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe";
          break;
        case "testoldal.hu":   //éles oldal
            $recaptchaSecret = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
          break;
        case "www.fzolee.hu":
            $recaptchaSecret = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
          break;
      }
    $_POST['server'] = $_SERVER["SERVER_NAME"];

    $recaptcha = new ReCaptcha( $recaptchaSecret, new \ReCaptcha\RequestMethod\CurlPost() );
        
    // we validate the ReCaptcha field together with the user's IP address        
    $response = $recaptcha->verify( $g_recaptcha_response, $_SERVER['REMOTE_ADDR'] );

    if ( !( $response->isSuccess() ) ) {
        throw new \Exception( $RecaptchaWasNotValidated );
    }
    
    // Email összeállítása
    $emailTextHTML .="<table>";
    // everything went well, we can compose the message, as usually  
    
    foreach ($_POST as $key => $value) {
        // If the field exists in the $fields array, include it in the email
        if ( isset( $fields[ $key ] ) ) {
            $emailText .= "$fields[$key]: $value\n";
            $emailTextHTML .= "<tr><td><strong>$fields[$key]:</strong></td><td>$value</td></tr>";
        }
    }    
    $ReplayToEmail = isset($_POST["email"]) ? $_POST["email"] : "";
            
    $emailTextHTML .= "</table><hr />";
        
    // Gmail App password leírása
    // https://mailtrap.io/blog/phpmailer-gmail/?fbclid=IwAR0LgfIVH_35GUYw0Z56xoVzcUbY0txV8oiGaa2mikJWeBjqu6PWTIwC8-E              
    $mail = new PHPMailer();
    $mail->Mailer     = "smtp";
    $mail->isSMTP();    
    $mail->SMTPAuth   = true;                         // authentikáció előírása
    
    $mail->SMTPDebug  = SMTP::DEBUG_OFF;
    $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;     // titkosítás: tls/ssl
    $mail->Port       = 587;                       // Set the SMTP port number - 587 for authenticated TLS 465    
    $mail->Host       = "smtp.gmail.com";     // SMTP szerver $mail->Host = gethostbyname("smtp.gmail.com");
    $mail->Username   = "testoldal@gmail.com";    // Küldő, authentikáló adatai Google Accounttal lehet létrehozni
    $mail->Password   = "kuqycdsfgjiplscxx";  // Gmail kulcskészítés
    // Email test esetén
    if($emailtest){
        $mail->SMTPDebug  = SMTP::DEBUG_SERVER;
        $mail->Port       = 625;                        // Set the SMTP port number - 587 for authenticated TLS 465    
        $mail->Host       = "mail.fzolee.hu";           // SMTP szerver $mail->Host = gethostbyname("smtp.gmail.com");
        $mail->Username   = "usernev@fzolee.hu";             // Küldő, authentikáló adatai
        $mail->Password   = "eredeti jelszó";                 // A küldő jelszava        
        $mail->SMTPAutoTLS = false;
    }

    $mail->SetFrom( "testoldal@gmail.com", $fromName );       // A küldő email címe
    $mail->AddAddress( "testoldal@gmail.com", $sendToName );  // A címzett email címe és neve
    $mail->addReplyTo( $ReplayToEmail );                                // A válasz email cím. Az űrlap email címe
    
    // Ékezetes címek miatt
    $mail->CharSet="UTF-8";                                          
    $mail->Subject = "=?UTF-8?B?".base64_encode($subject)."?=";
    $mail->isHTML(true);
    $mail->msgHTML( $emailTextHTML );
    
    // Hibaüzenetek eltüntetése
    ob_start();
    if( !$mail->send() ){
        throw new \Exception("Mailer Error:" .$mail->ErrorInfo);
    };
    $responseArray = array('type' => 'success', 'message' => $okMessage);
    $out = ob_get_contents();
    ob_end_clean();
} catch (\Exception $e) {
    $responseArray = array('type' => 'danger', 'message' => $e->getMessage());
}

header('Content-Type: application/json');
echo json_encode($responseArray);

Ha a fenti oldalt AJAX-szal javascript segítségével POST-tal hívjuk meg, akkor JSON-ként kapjuk vissza a hibaüzenetet.

Javascript kód:

var gdpr = true;
(function($, gdpr){

  // Validator files are included in the download package
  // otherwise download from http://1000hz.github.io/bootstrap-validator
  $('form#contact-form').validator();
  
  // when the form is submitted
  $('form#contact-form').submit( function (e) {    
    
    if ( !e.isDefaultPrevented() ) {    // if the validator does not prevent form submit
      var url = SiteUrl + "/lib/request.php";
  
      // POST values in the background the the script URL
      $.ajax({
        type: "POST",
        url: url,
        data: $(this).serialize(),
        success: function (data)
        {           
          // we recieve the type of the message: success x danger and apply it to the 
          var messageAlert = 'alert-' + data.type;
          var messageText = data.message;
  
          // let's compose Bootstrap alert box HTML
          var alertBox = '<div class="alert ' + messageAlert + ' alert-dismissable">';
          alertBox = alertBox + '<button id="messageAlert" type="button" class="close" ';
          alertBox = alertBox + 'data-dismiss="alert" aria-hidden="true">&times;</button> ' + messageText + '</div>';
                    
          // If we have messageAlert and messageText
          if (messageAlert && messageText) {
            // inject the alert to .messages div in our form
            $('#contact-form').find('.messages').html(alertBox);
            // empty the form
            $('#contact-form')[0].reset();
            
            $("button#messageAlert").click(function(){
              $("div.messages").html("");
            });          
          }
        }
      });
      return false;
    }
  })

  // ------------- reCaptcha kód formázása -----------
  $('iframe[title^="reCAPTCHA]').on("load", function(){
    $(this).css("width","75%");    
  })
})(jQuery, gdpr);

A HTML kód:

<!doctype html>
<html lang="hu">
   <head>
      <title>Test oldal </title>
      <meta charset="utf-8" />
    </head>
    <body>
            <div id="request-container">
            <h2 id="request">Ajánlatkérés</h2>
            <div id="request-content">
                  <form id="contact-form" method="GET" action="lib/request.php" role="form">

    <div class="messages"></div>

    <div class="controls">

        <div class="row">
            <div class="col-md-6">
                <div class="form-group">
                    <label for="form_lastname">Vezetéknév *</label>
                    <input id="form_lastname" type="text" value="Fábián"name="surname" class="form-control" placeholder="Kérlek írd be a vezetékneved *" required="required" data-error="A vezetéknév kötelező.">
                    <div class="help-block with-errors"></div>
                </div>
            </div>

            <div class="col-md-6">
                <div class="form-group">
                    <label for="form_name">Keresztnév *</label>
                    <input id="form_name" type="text" value="Zoltán"name="name" class="form-control" placeholder="Kérjük írd be a keresztneved *" required="required" data-error="A keresztnév kötelező.">
                    <div class="help-block with-errors"></div>
                </div>
            </div>
        </div>
        <div class="row">
            <div class="col-md-6">
                <div class="form-group">
                    <label for="form_email">Email *</label>
                    <input id="form_email" type="email" value="fz@fzolee.hu"name="email" class="form-control" placeholder="Kérjük írd be az email címed *" required="required" data-error="Érvényes email cím használata szükséges.">
                    <div class="help-block with-errors"></div>
                </div>
            </div>
            <div class="col-md-6">
                <div class="form-group">
                    <label for="form_need">Válaszd ki az üzenet típusát *</label>
                    <select id="form_need" name="need" class="form-control" required="required" data-error="Válaszd ki az üzenet típusát.">
                        <option value=""></option>
                        <option value="Request quotation" selected>Árajánlat kérés</option>
                        <option value="Request order status">A Rendelés állapota</option>
                        <option value="Request copy of an invoice">Számlamásolat kérése</option>
                        <option value="Other">Rgyéb</option>
                    </select>
                    <div class="help-block with-errors"></div>
                </div>
            </div>
        </div>
        <div class="row">
            <div class="col-md-12">
                <div class="form-group">
                    <label for="form_message">Üzenet *</label>
                    <textarea id="form_message" name="message" class="form-control" placeholder="Az üzenet szövege *" rows="4" required="required" data-error="Kérjük hagyjál üzenetet.">2024.03.28 07:03:53 - Teszt szöveg</textarea>
                    <div class="help-block with-errors"></div>
                </div>
            </div>
            <div class="col-md-12">
                <input id="request-submit" type="submit" class="btn btn-success btn-send" value="Küld el az üzenetet">
            </div>
        </div>
        <div class="row">
            <div class="col-md-12">
                <p class="text-muted"><strong>*</strong> Ezek kötelezően kitöltendő mezők! </p>
            </div>
        </div>
    </div>
          <div class="g-recaptcha"
               <!-- Nyilvános kulcs. A példában a localhost kulcs szerepel -->
               data-sitekey="6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI"
               data-callback="" and data-expired-callback="">    
           </div>    
     </form>                                 
  </div>
</div>
         
<script src="assets/jquery-3.7.1.min.js"></script>
<script src="assets/popperjs/popper.min.js"></script>
<script src="assets/bootstrap-5.3.3-dist/js/bootstrap.bundle.min.js"></script>
<script>         
         var SiteUrl = "/p/request";
</script>
<script src="js/request.js"></script> 
</body>

A példában nincsen reCaptcha, azt a következő cikkben írom le!