Send mail via SMTP with self-signed certificate with Laravel 5.2
Posted on 25 May 2016
2 minute read
I’m currently writing an application using Laravel 5.2 but needed to send mail via SMTP with self-signed certificate. I didn’t want to edit the SwiftMailer library directly for obvious reasons.
The version of Laravel currently being used for this application is 5.2.6, which comes with SwiftMailer 5.4.1
. We need version 5.4.2
or higher so we can use the setStreamOptions()
method of Swift_SmtpTransport
, so I updated this via Composer.
config/mail.php
I added some new options to the config/mail.php file:
'ssloptions' => [
'allow_self_signed' => env('MAIL_SSLOPTIONS_ALLOW_SELF_SIGNED', false),
'verify_peer' => env('MAIL_SSLOPTIONS_VERIFY_PEER', true),
'verify_peer_name' => env('MAIL_SSLOPTIONS_VERIFY_PEER_NAME', true),
],
This sets up the SSL options we need and they can be overridden in the .env
file. These defaults are the same defaults that SwiftMailer uses out-of-the-box.
Laravel .env overrides
I then added the overrides in .env
:
MAIL_SSLOPTIONS_ALLOW_SELF_SIGNED=true
MAIL_SSLOPTIONS_VERIFY_PEER=false
MAIL_SSLOPTIONS_VERIFY_PEER_NAME=false
My whole MAIL
section in the .env
file looks like:
MAIL_DRIVER=smtp
MAIL_HOST=smtp.domain.com
MAIL_PORT=587
MAIL_USERNAME=username@example.com
MAIL_PASSWORD=my_email_password
MAIL_ENCRYPTION=tls
MAIL_SSLOPTIONS_ALLOW_SELF_SIGNED=true
MAIL_SSLOPTIONS_VERIFY_PEER=false
MAIL_SSLOPTIONS_VERIFY_PEER_NAME=false
Controller code
I then constructed the SmtpTransport and SmtpMailer manually in the controller and passed the mailer to the Mail facade:
// Send email notification
$transport = Swift_SmtpTransport::newInstance(
\Config::get('mail.host'),
\Config::get('mail.port'),
\Config::get('mail.encryption'))
->setUsername(\Config::get('mail.username'))
->setPassword(\Config::get('mail.password'))
->setStreamOptions(['ssl' => \Config::get('mail.ssloptions')]);
$mailer = Swift_Mailer::newInstance($transport);
Mail::setSwiftMailer($mailer);
Send the mail via SMTP with self-signed certificate
We can then use the Mail facade as per the Laravel docs:
Mail::send(
'emails.html-email-template', $templateData, function (\Illuminate\Mail\Message $message) {
$message->subject('Email notification');
$message->from('from@example.com', 'From name');
$message->to('to@example.com', 'To name');
}
);
Finally, I was able to send the email notifications without SSL errors.