PHPMailerでOAuth2.0認証してGMailを送信する
2023-12-18 記載
概要 : GMailは2段階認証とOAuth2.0の認証の選択が可能。両方を動かしてみます。
Keyword :
Gmailを例に、Gmailのアカウントを用いてメール送信する設定をしてみます。
Gmailは認証方法として、OAuth2.0と2段階認証のふたつがあります。前回は2段階認証をしましたので、今回はOAuth2.0で送ります。
Gメールのアカウントはすでに持っているものとします。
myaccount@gmail.com
と説明上はします。
IMAPは有効になっているとします。
Google Developers Consoleを表示します。
https://console.developers.google.com/
新しいプロジェクトを作成します。名前はお好きに。
ここでは以下にします。
Cloudfree-Default-Project
バーガーメニュー→APIとサービス→OAuth同意画面
ユーザーは外部しか選べないので「外部」
アプリ情報
アプリ名:GMailSendmail (自分がわかる名前であればよい)
ユーザーサポートメール:アカウントのGMail
アプリのロゴ:省略可能 (或いはこちらをご自由にどうぞ→)
アプリのドメイン:省略
承認済みドメイン:cloudfree.jp
デベロッパーの連絡先情報:アカウントのGMail
=>保存して次へ
スコープ(関係の画面)
=>保存して次へ
テストユーザー(関係の画面)
=>保存して次へ
=>ダッシュボードに戻る
認証情報→認証情報を作成→OAuthクライアントID
アプリケーションの種類:ウェブアプリケーション
名前:APP_Cloudfree-Sendmail (お好きな名前で適当に)
承認済みのリダイレクト URI:
https://developers.google.com/oauthplayground
=>作成
クライアント ID
クライアント シークレット
が表示されますので控えておきます。
アプリを公開します。
公開ステータス:本番環境
承認済みのリダイレクト URI の画面を開く
https://developers.google.com/oauthplayground
右上)歯車→Use your own OAuth credentialsにチェック
OAuth Client ID:
OAuth Client secret:
に控えたクライアント ID・クライアント シークレットを入力してClose
リストからGMailAPI https://mail.google.com/ をチェック
→Authorize APIs
アカウントを選択→詳細→GMailSendmail(安全ではないページ)に移動
GMailSendmail が Google アカウントへのアクセスを求めています
の画面で→続行
切り替わった画面の
Authorization code:
の下
Exchange authorization code for tokens をクリック
表示更新された画面の右「Request / Response」の下、
JSONでrefresh_token:が表示されていますので値を控えます。
これで以下の3つが揃いました。GMailでの事前作業は完了です。
クライアント ID
クライアント シークレット
リフレッシュトークン
前回、ComposerでPHPMailerをセットアップしましたので、ここでは省きます。追加で
composer require league/oauth2-google
のみセットアップします。
場所は例として htdocs\maillib にします。(2023-12-21のVersion)
composer require league/oauth2-google
Using version ^4.0 for league/oauth2-google
./composer.json has been updated
Running composer update league/oauth2-google
Loading composer repositories with package information
Updating dependencies
Lock file operations: 11 installs, 0 updates, 0 removals
- Locking guzzlehttp/guzzle (7.8.1)
- Locking guzzlehttp/promises (2.0.2)
- Locking guzzlehttp/psr7 (2.6.2)
- Locking league/oauth2-client (2.7.0)
- Locking league/oauth2-google (4.0.1)
- Locking paragonie/random_compat (v9.99.100)
- Locking psr/http-client (1.0.3)
- Locking psr/http-factory (1.0.2)
- Locking psr/http-message (2.0)
- Locking ralouphie/getallheaders (3.0.3)
- Locking symfony/deprecation-contracts (v3.4.0)
Writing lock file
Installing dependencies from lock file (including require-dev)
Package operations: 11 installs, 0 updates, 0 removals
- Installing symfony/deprecation-contracts (v3.4.0): Extracting archive
- Installing psr/http-message (2.0): Extracting archive
- Installing psr/http-client (1.0.3): Extracting archive
- Installing ralouphie/getallheaders (3.0.3): Extracting archive
- Installing psr/http-factory (1.0.2): Extracting archive
- Installing guzzlehttp/psr7 (2.6.2): Extracting archive
- Installing guzzlehttp/promises (2.0.2): Extracting archive
- Installing guzzlehttp/guzzle (7.8.1): Extracting archive
- Installing paragonie/random_compat (v9.99.100): Extracting archive
- Installing league/oauth2-client (2.7.0): Extracting archive
- Installing league/oauth2-google (4.0.1): Extracting archive
4 package suggestions were added by new dependencies, use `composer suggest` to see details.
Generating autoload files
5 packages you are using are looking for funding.
Use the `composer fund` command to find out more!
ではphpから送ってみることにします。
myaccount@gmail.com が送信元。
dummymail@gmail.com を送付先とします。
3つのコードを、それらしく捏造して(^^;
クライアント ID:
123456789012-ClientIDxxxx7777yyyy8888zzzz9999.apps.googleusercontent.com
クライアント シークレット:
SECRET-GoogleAPI0000aaaa1111bbbb2222
リフレッシュトークン:
1//04_RefreshToken-abcde_55667788eeff_mnopqr-A12B34C56D78
htdocs\maillib\sendmail_gmail_oauth.phpをコードを書くファイルとします。
<?php
require_once 'vendor/autoload.php';
require_once 'vendor/phpmailer/phpmailer/language/phpmailer.lang-ja.php';
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\OAuth;
use PHPMailer\PHPMailer\Exception;
use League\OAuth2\Client\Provider\Google;
$mail = new PHPMailer(true);
//$mail->SMTPDebug = 2; //デバッグ用 2
$mail->setLanguage('ja', 'vendor/phpmailer/phpmailer/language/');
$mail->CharSet = "utf-8";
$mail->Encoding = "base64";
//認証設定
$mail->isSMTP();
$mail->Host = 'smtp.gmail.com';
$mail->SMTPAuth = true;
$mail->Port = 587;
$mail->SMTPSecure = 'tls';
$mail->AuthType = 'XOAUTH2';
$provider = new Google([
'clientId' => '123456789012-ClientIDxxxx7777yyyy8888zzzz9999.apps.googleusercontent.com',
'clientSecret' => 'SECRET-GoogleAPI0000aaaa1111bbbb2222',
]);
$mail->setOAuth(new OAuth([
'provider' => $provider,
'clientId' => '123456789012-ClientIDxxxx7777yyyy8888zzzz9999.apps.googleusercontent.com',
'clientSecret' => 'SECRET-GoogleAPI0000aaaa1111bbbb2222',
'refreshToken' => '1//04_RefreshToken-abcde_55667788eeff_mnopqr-A12B34C56D78',
'userName' => 'myaccount@gmail.com',
]));
$mail->Username = 'myaccount@gmail.com';
//差出人
$mail->setFrom('myaccount@gmail.com');
//宛先
$mail->addAddress('dummymail@gmail.com');
//件名
$mail->Subject = 'PHPMailerからOAuth認証して送ります';
//本文
$mail->Body = "春はあけぼの。\nやうやう白くなりゆく山ぎは\nすこしあかりて";
//メール送信
try {
$mail->send();
echo '届きましたか?';
} catch (Exception $e) {
echo '失敗: ', $mail->ErrorInfo.PHP_EOL;
}
こちらは
承認済みドメイン:cloudfree.jp
としましたのでローカルで実行させてもエラーになります。
cloudfreeサーバにあげて、サーバで実行させると成功するでしょう。
Google Developers Console にて 承認済みドメイン を追加設定すれば、同じコードで別のサーバでも送信可能です。ただしhttpsで正式な認証をとっているサーバに限られるようです。私がローカルで立てたオレオレ認証局はlocalhostですからお話になりません。
しかしそれはOAuth2.0がセキュリティには良いということであるんですが。