I wanted to use a Gmail address with Kirby’s email utility, but if you use the Gmail SMTP server with standard username/password authentication for Kirby emails, you need set your Gmail account to ‘allow less secure apps’. I didn’t want to do this (there’s a reason this isn’t the default) but the alternative is to authenticate with OAuth2, which isn’t straightforward to setup. I thought I’d post the process I went through here because I couldn’t find it elsewhere.
Thanks to @ahmetbora for pointing me to the beforeSend
callback where I could include the required OAuth logic. If someone knows a more elegant solution I’m happy to hear it.
1. Install packages
PHPMailer comes standard with Kirby 3, but it needs the OAuth2 Google Provider package to authenticate. This package is also needed in the get_oauth_token.php
script that comes with PHPMailer to get your Gmail refresh token (see step 2 below):
composer require league/oauth2-google
If you want to keep your credentials in a .env
file for security reasons, you can use the DotEnv plugin:
composer require bnomei/kirby3-dotenv
2: Get authentication credentials
Before you can start sending emails, you need to authorise your web app first. Create a project in the Google developer console and obtain a client ID and client secret. Then use the get_oauth_token.php
script provided by PHPMailer to get a refresh token. This is the most complicated part, but there’s a detailed step by step tutorial here.
3: Configure Kirby
In config.php
add the following:
<?php
use League\OAuth2\Client\Provider\Google;
use PHPMailer\PHPMailer\OAuth;
return [
'email' => [
'transport' => [
'type' => 'smtp',
'host' => 'smtp.gmail.com',
'port' => 587,
'security' => true,
'auth' => true,
],
'beforeSend' => function ($mailer) {
$mailer->AuthType = 'XOAUTH2';
// if the kirby3-dotenv plugin is installed,
// env() reads your credentials from a .env file
$email = env('EMAIL');
$clientId = env('GMAIL_CLIENT_ID');
$clientSecret = env('GMAIL_CLIENT_SECRET');
$refreshToken = env('GMAIL_REFRESH_TOKEN');
$provider = new Google(
[
'clientId' => $clientId,
'clientSecret' => $clientSecret,
]
);
$mailer->setOAuth(
new OAuth(
[
'provider' => $provider,
'clientId' => $clientId,
'clientSecret' => $clientSecret,
'refreshToken' => $refreshToken,
'userName' => $email,
]
)
);
return $mailer;
},
],
];