Some of the gmail accounts are protected with 2-step auth and you need app specific password. Is that the case with this?
Email: Gmail Authentication Issues
I'm trying to get email setup with my Laravel application.
Here's my environment variables for the Mail:
MAIL_DRIVER=smtp
MAIL_HOST=smtp.gmail.com
MAIL_PORT=465
MAIL_USERNAME=tylernathanreed
MAIL_PASSWORD=**********
MAIL_ENCRYPTION=ssl
And here's the error I'm getting:
Swift_TransportException in AuthHandler.php line 181:
Failed to authenticate on SMTP server with username "tylernathanreed" using 2 possible authenticators
I've tried a number of things already:
- Allowing less secure Apps: https://myaccount.google.com/security#connectedapps
- Using the Display Unlock Captcha: https://accounts.google.com/DisplayUnlockCaptcha
- Putting the Password in Quotations
- Adding the @gmail suffix to the Username
I haven't messed with mailers since Laravel 4, so I'm a bit out of touch.
Also, I'm using GoDaddy to host my project. As far as I can tell, they're not doing anything to break this. And I'm running Laravel 5.1.
Any ideas on what I'm doing wrong?
@premsaurav Sure. Here's the particular scenario I'm testing:
A User makes an account, and I want to send them an email to validate their email address. When a user registers, the UserHasRegistered event fires, which is picked up by the EmailValidationToken listener. The listener looks like this:
<?php
namespace App\Listeners;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use App\Events\UserHasRegistered;
use App\Mailers\AppMailer as Mailer;
use App\Support\Facades\Flash;
class EmailValidationToken
{
/**
* The Mailer for the Application
*
* @var Mailer
*/
public $mailer;
/**
* Create the event listener.
*
* @param Mailer $mailer
*
* @return void
*/
public function __construct(Mailer $mailer)
{
$this->mailer = $mailer;
}
/**
* Handle the event.
*
* @param UserHasRegistered $event
*
* @return void
*/
public function handle(UserHasRegistered $event)
{
$this->mailer->sendValidationRequest($event->user);
Flash::success('You have been sent a Validation Request to your Email Account.');
}
}
The Mailer here is technically my AppMailer class, as seen in the use declarations. The AppMailer looks like this:
<?php
namespace App\Mailers;
use Illuminate\Contracts\Mail\Mailer;
use App\Models\User;
class AppMailer
{
protected $mailer;
protected $from;
protected $to;
protected $view;
protected $data = [];
public function __construct(Mailer $mailer)
{
$this->mailer = $mailer;
}
/**
* Delivers the View as an Email to the specified Receiver, given
* a Sender and their Name.
*
* @param View $view The View for the Email.
* @param array $data The Data for the View.
* @param string $to The Email Address to send the Email to.
* @param string $from The Email Address that sent the Email.
* @param string $name The Name of the Person that sent the Email.
*
* @return void
*/
public function deliver($view, $data, $to, $from = 'admin@example.com', $name = 'No-Reply')
{
$this->mailer->send($view, $data, function($message) use ($from, $to, $name)
{
$message->from($from, $name)
->to($to);
});
}
/**
* Sends an Account Validation Link to the specified User.
*
* @param User $user The specified User.
*
* @return void;
*/
public function sendValidationRequest(User $user)
{
$this->deliver('emails.validate', compact('user'), $user->email);
}
/**
* Sends a Password Reset to the specified User.
*
* @param User $user The specified User.
*
* @return void;
*/
public function sendPasswordResetRequest(User $user)
{
$this->deliver('emails.password_reset', compact('user'), $user->email);
}
}
...and, I just figured it out. I forgot to change my template:
public function deliver($view, $data, $to, $from = 'admin@example.com', $name = 'No-Reply')
I changed this to:
public function deliver($view, $data, $to, $from = null, $name = 'No-Reply')
{
// Resolve From Address
if($from == null)
$from = env('MAIL_USERNAME');
...
}
And it now works! Thanks guys!
Please or to participate in this conversation.