Search code examples
phpgmailphpmailer

Need to send mail from gmail using php mailer without enabling "less secure app" and generating "app password"


I am trying to send the mail from my gmail account using php mailer.

I know that in order to send the mail using the php mailer, we need to enable "less secure app" from our gmail account setting.

There is also an option that without enabling the "less secure app", we can use "APP password", by enabling the two step verification to send mail from the less secure app.

But the problem is using the "APP password", I am not able to send the mail from the php mailer got an error that username and password not accepted.

I searched and found that, we can't able to send mail from less secured app using the "APP password". Found from this link https://support.google.com/accounts/answer/185833?hl=en&authuser=5

Iam using the following php mailer code to send mail:

<?php
// Import PHPMailer classes into the global namespace
// These must be at the top of your script, not inside a function
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
// Load Composer's autoloader
require 'vendor/autoload.php';
// Instantiation and passing `true` enables exceptions
$mail = new PHPMailer(true);
try {
//Server settings
$mail->SMTPDebug = 2;                                       // Enable       verbose debug output
$mail->isSMTP();                                            // Set mailer to use SMTP
$mail->Host       = 'ssl://smtp.gmail.com';                 // Specify main and backup SMTP servers
$mail->SMTPAuth   = true;                                   // Enable SMTP authentication
$mail->Username   = username;
$mail->Password   = password;
$mail->SMTPSecure = 'ssl';                                  // Enable TLS encryption, `ssl` also accepted
$mail->Port       = 465;
//Recipients
$mail->setFrom('[email protected]', 'Test');
$mail->addAddress('[email protected]', 'Test1');     // Add a recipient
$mail->addAddress('[email protected]');               // Name is optional
$mail->addReplyTo('[email protected]', 'Test');
// Content
$mail->isHTML(true);                                  // Set email format to HTML
$mail->Subject = 'Here is the subject';
$mail->Body    = 'This is the HTML message body <b>in bold!</b>';
$mail->AltBody = 'This is the body in plain text for non-HTML mail clients';
$mail->send();
echo 'Message has been sent';
} catch (Exception $e) {
echo "Message could not be sent. Mailer Error: {$mail->ErrorInfo}";
}

When using the "APP password" the following error message coming.

2019-09-04 07:24:15 CLIENT -> SERVER: EHLO localhost
2019-09-04 07:24:15 CLIENT -> SERVER: AUTH LOGIN
2019-09-04 07:24:16 CLIENT -> SERVER: <credentials hidden>
2019-09-04 07:24:16 CLIENT -> SERVER: <credentials hidden>
2019-09-04 07:24:16 SMTP ERROR: Password command failed: 535-5.7.8 Username and Password not accepted. Learn more at535 5.7.8 https://support.google.com/mail/?p=BadCredentials z12sm8871955pfj.41 - gsmtp
SMTP Error: Could not authenticate.
2019-09-04 07:24:16 CLIENT -> SERVER: QUIT
SMTP Error: Could not authenticate.
Message could not be sent. Mailer Error: SMTP Error: Could not authenticate.

Please give a solution to send mail without enabling the "less secure app" and using gmail "APP password"

I also used the third option - XOAUTH2 authentication to send the mail. The below is my code:

    <?php
    /**
     * This example shows how to send via Google's Gmail servers using XOAUTH2 authentication.
     */
    //Import PHPMailer classes into the global namespace
    use PHPMailer\PHPMailer\PHPMailer;
    use PHPMailer\PHPMailer\OAuth;
    // Alias the League Google OAuth2 provider class
    use League\OAuth2\Client\Provider\Google;
    //SMTP needs accurate times, and the PHP time zone MUST be set
    //This should be done in your php.ini, but this is how to do it if you don't have access to that
    date_default_timezone_set('Etc/UTC');
    //Load dependencies from composer
    //If this causes an error, run 'composer install'
    require 'vendor/autoload.php';

    $send_to_address = $_GET['email'];
    $send_to_name = $_GET['name'];


    //Create a new PHPMailer instance
    $mail = new PHPMailer;
    //Tell PHPMailer to use SMTP
    $mail->isSMTP();
    //Enable SMTP debugging
    // 0 = off (for production use)
    // 1 = client messages
    // 2 = client and server messages
    $mail->SMTPDebug = 2;
    //Set the hostname of the mail server
    $mail->Host = 'smtp.gmail.com';
    //Set the SMTP port number - 587 for authenticated TLS, a.k.a. RFC4409 SMTP submission
    $mail->Port = 587;
    //Set the encryption system to use - ssl (deprecated) or tls
    $mail->SMTPSecure = 'tls';
    //Whether to use SMTP authentication
    $mail->SMTPAuth = true;
    //Set AuthType to use XOAUTH2
    $mail->AuthType = 'XOAUTH2';
    //Fill in authentication details here
    //Either the gmail account owner, or the user that gave consent
    $email = '[email protected]';
    $clientId = '315061611767-fitjjndpsi6uo1j7hn923loaa0dg1ch1.apps.googleusercontent.com';
    $clientSecret = '3m-47D5Ojvpnfqp5qxxQ2WLn';
    //Obtained by configuring and running get_oauth_token.php
    //after setting up an app in Google Developer Console.
    $refreshToken = '4/qgEr9g7oYr2jk-q2YZpDbD5GCKK0oMdUHrVwsww9t5tXey5zr4fcjhS4Mk25rLcklEkUl4F20iKKmy-CAMme5r8';
    //Create a new OAuth2 provider instance
    $provider = new Google(
        [
            'clientId' => $clientId,
            'clientSecret' => $clientSecret,
        ]
    );
    //Pass the OAuth provider instance to PHPMailer
    $mail->setOAuth(
        new OAuth(
            [
                'provider' => $provider,
                'clientId' => $clientId,
                'clientSecret' => $clientSecret,
                'refreshToken' => $refreshToken,
                'userName' => $email,
            ]
        )
    );
    //Set who the message is to be sent from
    //For gmail, this generally needs to be the same as the user you logged in as
    $mail->setFrom($email, 'Gudbiz');
    //Set who the message is to be sent to
    $mail->addAddress($send_to_address, $send_to_name);
    //Set the subject line
    $mail->Subject = 'PHPMailer GMail XOAUTH2 SMTP test';
    //Read an HTML message body from an external file, convert referenced images to embedded,
    //convert HTML into a basic plain-text alternative body
    $mail->CharSet = 'utf-8';
    //$mail->msgHTML(file_get_contents('contentsutf8.html'), __DIR__);
    $mail->Body    = 'This is the HTML message body <b>in bold!</b>';
    //Replace the plain text body with one created manually
    $mail->AltBody = 'This is a plain-text message body';
    //Attach an image file
    //$mail->addAttachment('images/phpmailer_mini.png');
    //send the message, check for errors
    if (!$mail->send()) {
        echo "Mailer Error: " . $mail->ErrorInfo;
    } else {
        echo "Message sent!";
    }

Using above code i get the output like below:

    2019-09-04 11:52:57 SERVER -> CLIENT: 220 smtp.gmail.com ESMTP v8sm7946021pje.6 - gsmtp
    2019-09-04 11:52:57 CLIENT -> SERVER: EHLO testapi.howorkforce.com
    2019-09-04 11:52:58 SERVER -> CLIENT: 250-smtp.gmail.com at your service, [13.126.85.98]250-SIZE 35882577250-8BITMIME250-STARTTLS250-ENHANCEDSTATUSCODES250-PIPELINING250-CHUNKING250 SMTPUTF8
    2019-09-04 11:52:58 CLIENT -> SERVER: STARTTLS
    2019-09-04 11:52:58 SERVER -> CLIENT: 220 2.0.0 Ready to start TLS
    2019-09-04 11:52:58 CLIENT -> SERVER: EHLO testapi.howorkforce.com
    2019-09-04 11:52:58 SERVER -> CLIENT: 250-smtp.gmail.com at your service, [13.126.85.98]250-SIZE 35882577250-8BITMIME250-AUTH LOGIN PLAIN XOAUTH2 PLAIN-CLIENTTOKEN OAUTHBEARER XOAUTH250-ENHANCEDSTATUSCODES250-PIPELINING250-CHUNKING250 SMTPUTF8

But the mail didn't send. Please suggest a solution for this.

Please find the additional info with "SMTP debug 4"

    2019-09-05 11:51:05 Connection: opening to smtp.gmail.com:587, timeout=300, options=array()
    2019-09-05 11:51:05 Connection: opened
    2019-09-05 11:51:05 SMTP INBOUND: "220 smtp.gmail.com ESMTP l23sm2317472pjy.3 - gsmtp"
    2019-09-05 11:51:05 SERVER -> CLIENT: 220 smtp.gmail.com ESMTP l23sm2317472pjy.3 - gsmtp
    2019-09-05 11:51:05 CLIENT -> SERVER: EHLO localhost
    2019-09-05 11:51:06 SMTP INBOUND: "250-smtp.gmail.com at your service, [103.125.155.132]"
    2019-09-05 11:51:06 SMTP INBOUND: "250-SIZE 35882577"
    2019-09-05 11:51:06 SMTP INBOUND: "250-8BITMIME"
    2019-09-05 11:51:06 SMTP INBOUND: "250-STARTTLS"
    2019-09-05 11:51:06 SMTP INBOUND: "250-ENHANCEDSTATUSCODES"
    2019-09-05 11:51:06 SMTP INBOUND: "250-PIPELINING"
    2019-09-05 11:51:06 SMTP INBOUND: "250-CHUNKING"
    2019-09-05 11:51:06 SMTP INBOUND: "250 SMTPUTF8"
    2019-09-05 11:51:06 SERVER -> CLIENT: 250-smtp.gmail.com at your service, [103.125.155.132]250-SIZE 35882577250-8BITMIME250-STARTTLS250-ENHANCEDSTATUSCODES250-PIPELINING250-CHUNKING250 SMTPUTF8
    2019-09-05 11:51:06 CLIENT -> SERVER: STARTTLS
    2019-09-05 11:51:06 SMTP INBOUND: "220 2.0.0 Ready to start TLS"
    2019-09-05 11:51:06 SERVER -> CLIENT: 220 2.0.0 Ready to start TLS
    2019-09-05 11:51:06 CLIENT -> SERVER: EHLO localhost
    2019-09-05 11:51:06 SMTP INBOUND: "250-smtp.gmail.com at your service, [103.125.155.132]"
    2019-09-05 11:51:06 SMTP INBOUND: "250-SIZE 35882577"
    2019-09-05 11:51:06 SMTP INBOUND: "250-8BITMIME"
    2019-09-05 11:51:06 SMTP INBOUND: "250-AUTH LOGIN PLAIN XOAUTH2 PLAIN-CLIENTTOKEN OAUTHBEARER XOAUTH"
    2019-09-05 11:51:06 SMTP INBOUND: "250-ENHANCEDSTATUSCODES"
    2019-09-05 11:51:06 SMTP INBOUND: "250-PIPELINING"
    2019-09-05 11:51:06 SMTP INBOUND: "250-CHUNKING"
    2019-09-05 11:51:06 SMTP INBOUND: "250 SMTPUTF8"
    2019-09-05 11:51:06 SERVER -> CLIENT: 250-smtp.gmail.com at your service, [103.125.155.132]250-SIZE 35882577250-8BITMIME250-AUTH LOGIN PLAIN XOAUTH2 PLAIN-CLIENTTOKEN OAUTHBEARER XOAUTH250-ENHANCEDSTATUSCODES250-PIPELINING250-CHUNKING250 SMTPUTF8
    2019-09-05 11:51:06 Auth method requested: XOAUTH2
    2019-09-05 11:51:06 Auth methods available on the server: LOGIN,PLAIN,XOAUTH2,PLAIN-CLIENTTOKEN,OAUTHBEARER,XOAUTH

Solution

  • I got the solution. the refresh token i used was the one, which takes me to this much headache.

    The "refresh token" i used was not valid. Once i regenerate the refresh token all seems to be fine. The mail is sending correctly.