<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Google Workspace &#8211; 記下來</title>
	<atom:link href="https://noter.tw/tag/google-workspace/feed/" rel="self" type="application/rss+xml" />
	<link>https://noter.tw</link>
	<description>一路上踩到的坑、遇到的問題，一點一滴記下來，希望能幫助到需要的人~</description>
	<lastBuildDate>Thu, 25 Apr 2024 08:54:06 +0000</lastBuildDate>
	<language>zh-TW</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.6.3</generator>

<image>
	<url>https://noter.tw/wp-content/uploads/cropped-old-1130742_1920-1-32x32.jpg</url>
	<title>Google Workspace &#8211; 記下來</title>
	<link>https://noter.tw</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>PHPMailer + Gmail OAuth2 寄信</title>
		<link>https://noter.tw/12780/phpmailer-gmail-oauth2-%e5%af%84%e4%bf%a1/</link>
					<comments>https://noter.tw/12780/phpmailer-gmail-oauth2-%e5%af%84%e4%bf%a1/#respond</comments>
		
		<dc:creator><![CDATA[黃小蛙]]></dc:creator>
		<pubDate>Thu, 25 Apr 2024 08:08:36 +0000</pubDate>
				<category><![CDATA[程式開發]]></category>
		<category><![CDATA[網頁後端]]></category>
		<category><![CDATA[技術相關]]></category>
		<category><![CDATA[OAuth]]></category>
		<category><![CDATA[建立 OAuth 用戶端 ID 憑證]]></category>
		<category><![CDATA[OAuth token]]></category>
		<category><![CDATA[Google Workspace]]></category>
		<category><![CDATA[PHP Gmail 寄信]]></category>
		<category><![CDATA[PHP 發送郵件]]></category>
		<category><![CDATA[get_oauth_token.php]]></category>
		<category><![CDATA[已授權的重新導向 URI]]></category>
		<category><![CDATA[oauth2 refresh token]]></category>
		<category><![CDATA[PHPMailer]]></category>
		<category><![CDATA[OAuth 用戶端 ID]]></category>
		<category><![CDATA[Gmail API]]></category>
		<category><![CDATA[Google Cloud 憑證]]></category>
		<category><![CDATA[PHPMailer Gmail OAuth2]]></category>
		<category><![CDATA[OAuth2 憑證]]></category>
		<category><![CDATA[XOAUTH2]]></category>
		<guid isPermaLink="false">https://noter.tw/?p=12780</guid>

					<description><![CDATA[<p>小蛙有個維護的系統使用 PHPMailer 透過 Gmail 帳號密碼發送郵件，近期收到 Google 寄來的通知「自 2024 年 9 月 30 日起，應用程式必須採用 OAuth 才能存取 Google Workspace 帳戶。系統將不再支援使用密碼 (應用程式密碼除外) 的存取行為。」為了避免哪一天突然通通都只支援 OAuth，趁現在有一點時間趕快來改一下。</p>
<p>這篇文章 <a rel="nofollow" href="https://noter.tw/12780/phpmailer-gmail-oauth2-%e5%af%84%e4%bf%a1/" data-wpel-link="internal">PHPMailer + Gmail OAuth2 寄信</a> 最早出現於 <a rel="nofollow" href="https://noter.tw" data-wpel-link="internal">記下來</a>。</p>
]]></description>
										<content:encoded><![CDATA[
<p>小蛙有個維護的系統使用 PHPMailer 透過 Gmail 帳號密碼發送郵件，近期收到 Google 寄來的通知「自 2024 年 9 月 30 日起，應用程式必須採用 OAuth 才能存取 Google Workspace 帳戶。系統將不再支援使用密碼 (應用程式密碼除外) 的存取行為。」為了避免哪一天突然通通都只支援 OAuth，趁現在有一點時間趕快來改一下。</p>



<span id="more-12780"></span>



<p>PHPMailer + Gmail OAuth 發信大概有幾個步驟：</p>



<ol class="my-li bg-darkblue wp-block-list">
<li><strong>安裝必要套件</strong>：使用 composer 在網站上安裝 phpmailer/phpmailer 及 league/oauth2-google 套件。</li>



<li><strong>建立 OAuth 2.0 用戶端 ID 憑證</strong>：到 Goolge Cloud 建立一個專案，並開啟 Gmail API 與建立一個 OAuth 2.0 用戶端 ID 憑證。</li>



<li><strong>取得 Refresh Token</strong>：設定 <code>get_oauth_token.php</code> 通過 OAuth 驗證，取得 Refresh Token。</li>



<li><strong>使用 PHPMailer 寄信</strong>：使用 PHPMailer 搭配前幾步得到的資訊寄送郵件。</li>
</ol>



<h2 class="wp-block-heading para">安裝必要套件</h2>



<p>需使用 composer 安裝必要套件，沒有 composer 的話可參考<a href="https://getcomposer.org/doc/00-intro.md" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external" class="wpel-icon-right">這邊<span class="wpel-icon wpel-image wpel-icon-6"></span></a>。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="shell" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">composer require phpmailer/phpmailer
composer require league/oauth2-google</pre>



<h2 class="wp-block-heading para">建立 OAuth 2.0 用戶端 ID 憑證</h2>



<h3 class="wp-block-heading para">啟用 Gmail API</h3>



<p>進入到 <a href="https://console.cloud.google.com/apis/dashboard" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external" class="wpel-icon-right">Google Cloud<span class="wpel-icon wpel-image wpel-icon-6"></span></a>，點擊左上方專案下拉選單 -> 新增專案 -> 輸入專案名稱，只要自己能辨識的即可，下面若有機構、位置，也都必須填寫上去</p>


<div class="wp-block-image">
<figure class="aligncenter is-resized"><img decoding="async" src="https://lh3.googleusercontent.com/pw/AP1GczP4fogGZPjU75mdxaeI0tKW2eGRS6FBUuaLQDUBqfgiO7knRvicztaTrMIUvqtpjyHL1b3_UA2wW586_u2pjqPXf2i5JVbEQwBDqsgfF_49ZwFj4gnTYZxNYJ6CP86gNEcwB1UuMCIhRLv6_xQfPFlq=w666-h715-s-rw-gm" alt="PHPMailer + Gmail OAuth 寄信 1" style="width:500px" title="PHPMailer + Gmail OAuth2 寄信"></figure></div>


<p>專案建立完成後進入該專案，左側選擇「已啟用的 API 和服務」，點擊「啟用 API 和服務」</p>


<div class="wp-block-image">
<figure class="aligncenter is-resized"><img decoding="async" src="https://lh3.googleusercontent.com/pw/AP1GczMKjfxWGckFT4SDqI9q5OGQi6NYeo_gpu-MQduZVVo3A5ArRza7b9UuIB4DF8LMkVhGYIeyC8oGBTCOQcq0vh4m4SQIzI84ARFBNMbgCIoKTGo_FG8adK4gWlOjolBpIpv3Z4v0UDeI7X8-vnvo0S64=w714-h390-s-rw-gm" alt="PHPMailer + Gmail OAuth 寄信 2" style="width:500px" title="PHPMailer + Gmail OAuth2 寄信"></figure></div>


<p>找到並啟用 Gmail API</p>


<div class="wp-block-image">
<figure class="aligncenter is-resized"><img decoding="async" src="https://lh3.googleusercontent.com/pw/AP1GczN60kf2CLZeKdaaKKq_T_dfsTQ51TsKgzgjJoK5oPxoAi69KAAQuqX3GWE5u5nNGBe7zP7V3EKceOYUe2cHXtLpFjLAbQgOm9lJQ1FVRBInF3Up-pmebuYjoRS37QywSXmEJk1rrieIxFPiD-oemF-X=w594-h401-s-rw-gm" alt="PHPMailer + Gmail OAuth 寄信 3" style="width:400px" title="PHPMailer + Gmail OAuth2 寄信"></figure></div>


<h3 class="wp-block-heading para">建立 OAuth 用戶端 ID 憑證</h3>



<p>成功啟用 Gmail API 後，左側進入「憑證」選單 -> 點擊「建立憑證」 -> OAuth 用戶端 ID</p>


<div class="wp-block-image">
<figure class="aligncenter is-resized"><img decoding="async" src="https://lh3.googleusercontent.com/pw/AP1GczPJKZpCSzpeLLRDHvkcwdJD2f82V1YY0UX5OZE9ykHd8uya60uNODJxm49OV5r5Qmv3F1JLR1DFHrUrGDD2fMKWaHXiF2miu0JIAHax-roCaD5dAJI4A16PN-RdZG0xIlmNhSD3LIpm8fLS3FNqSA9x=w935-h456-s-rw-gm" alt="PHPMailer + Gmail OAuth 寄信 4" style="width:600px" title="PHPMailer + Gmail OAuth2 寄信"></figure></div>


<p>第一次建立需要先設定同意畫面，點擊「設定同意畫面」</p>


<div class="wp-block-image">
<figure class="aligncenter is-resized"><img decoding="async" src="https://lh3.googleusercontent.com/pw/AP1GczOGpbByPCfX_QYNdc3Tty8-pY4dMxWJQdOxwQobKf0GaWAvTLjax_su14ODzwzsrdZ2RsU8t8OwBr2b4TWiI8OQ7ZStwA_Av-K3l8dkgTFGtlVaWcV1sravgQpNQQcVt2MZwamni3tLnDlWAd54SrMe=w690-h276-s-rw-gm" alt="PHPMailer + Gmail OAuth 寄信 5" style="width:500px" title="PHPMailer + Gmail OAuth2 寄信"></figure></div>


<p>我們的目的是完成至少一次 OAuth 驗證取得 Refresh Token，這邊選「內部」就可以了</p>


<div class="wp-block-image">
<figure class="aligncenter is-resized"><img decoding="async" src="https://lh3.googleusercontent.com/pw/AP1GczPGy3-iYpG5LY2fG9QKVqTJAah6GW-_2JCtjqsHeeYV9y2dHxGjF_aW7IR-lFGfI3cnEJyLXg8h4p6x_AvY5CRhrizpFWg9Dc2aCUp-MDQ9_S6rgUDoKVxDP8hCWRUDNu29lPxlPo87aMlhY8pTL1gj=w679-h581-s-rw-gm" alt="PHPMailer + Gmail OAuth 寄信 6" style="width:400px" title="PHPMailer + Gmail OAuth2 寄信"></figure></div>


<p>應用程式名稱、使用者支援電子郵件及開發人員聯絡資訊為必填項目，其餘部份視情況填寫，填寫完成後點擊「儲存並繼續」。</p>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-1 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow"><div class="wp-block-image">
<figure class="aligncenter"><img decoding="async" src="https://lh3.googleusercontent.com/pw/AP1GczN61095TO7WUG8Jydw_-ZEoOhID5Y4tzbiDnmw_EIlI3ueo2-T-LMeWGh0oEkOosg26OKJulTg1vTsPF-uCZD-5oXDv_iPtwv4-vlFaaULC10U_zRvGVVxjAtYVKQYxdm-QAunv4opzFP9zcAP3zcHN=w679-h798-s-rw-gm" alt="PHPMailer + Gmail OAuth 寄信 7" style="object-fit:cover" title="PHPMailer + Gmail OAuth2 寄信"></figure></div></div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow"><div class="wp-block-image">
<figure class="aligncenter"><img decoding="async" src="https://lh3.googleusercontent.com/pw/AP1GczNQiuqmUzaJJl-XySD31aSUGYPYyVDAVZltwi4U-9m2cpKP-4gKABuJzPwt1Dg2HfeIHFasME78Z8_TRyyXzwcq_gwbpZpvd7UNRph2x2ekx6o4zuoMD1sGyutyLuIpulDbyxdU7OqLBtaW_Cl8opWg=w677-h862-s-rw-gm" alt="PHPMailer + Gmail OAuth 寄信 8" title="PHPMailer + Gmail OAuth2 寄信"></figure></div></div>
</div>



<p>第二步範圍部份直接留空，點擊「儲存並繼續」</p>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-2 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow"><div class="wp-block-image">
<figure class="aligncenter"><img decoding="async" src="https://lh3.googleusercontent.com/pw/AP1GczMBKau2JTNrXXjqDFkP6vISLfQa_hyHJQZRr_w9v9na-CXiiEKI5e8TO7t0C3wKt5v-8aYVfi4YgRvXzNvvJ4QkjXPVHZBtmBlt4H3FkXCyXPGKRSNUNObiptfhmJ1UEhYPT5loGB9gTJ6wZKmZvJNA=w676-h552-s-rw-gm" alt="PHPMailer + Gmail OAuth 寄信 9" title="PHPMailer + Gmail OAuth2 寄信"></figure></div></div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow"><div class="wp-block-image">
<figure class="aligncenter"><img decoding="async" src="https://lh3.googleusercontent.com/pw/AP1GczPL1myaeyJMZsXqKb_MX2HErqMs1VuvwGiBzmkDAyYLb4BoaNkDvV1DS72TAcrkCDLkkAsGJSavFnwjg_t-cq28V3ezmndNqK-Z2OqmDslV5_YMKhD8Kq8jk3Om8akIA3lSIImxgLQfyE3e28hJ5JIh=w676-h537-s-rw-gm" alt="PHPMailer + Gmail OAuth 寄信 10" title="PHPMailer + Gmail OAuth2 寄信"></figure></div></div>
</div>



<p>OAuth 同意畫面建立完成</p>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-3 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow"><div class="wp-block-image">
<figure class="aligncenter"><img decoding="async" src="https://lh3.googleusercontent.com/pw/AP1GczPNN115kjpIKr-OPaknHyw3-TG0PVuuC9RCkdtZP5YgXMIQ8tq4-IpdYERZJ4wm0X8CFzz4nmvnSuPMhuXXuvLHu-qoQbJ7VAuR-Nu28p6jfmQmgkYYzJm6PDPPONbVzFuUCR6vR745pdeEq9fxllq2=w675-h617-s-rw-gm" alt="PHPMailer + Gmail OAuth 寄信 11" title="PHPMailer + Gmail OAuth2 寄信"></figure></div></div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow"><div class="wp-block-image">
<figure class="aligncenter is-resized"><img decoding="async" src="https://lh3.googleusercontent.com/pw/AP1GczP6GUlp18EkN6JAvl90LMqTV67IcvEvLRLdIZN5eL-a97ABLE9FficqfhZqCGq8hrSjQBGRmyDuFp2FP7OSTC4iwXY5Eq_SPh39XTBoGN0NH2paLIG5b8UsF4cawd3WMvmaiEUSKJvyAX3eAolyW6C7=w676-h569-s-rw-gm" alt="PHPMailer + Gmail OAuth 寄信 12" style="width:416px;height:auto" title="PHPMailer + Gmail OAuth2 寄信"></figure></div></div>
</div>



<p>再回到「憑證」->「建立憑證」->「OAuth 用戶端 ID」</p>


<div class="wp-block-image">
<figure class="aligncenter is-resized"><img decoding="async" src="https://lh3.googleusercontent.com/pw/AP1GczPJKZpCSzpeLLRDHvkcwdJD2f82V1YY0UX5OZE9ykHd8uya60uNODJxm49OV5r5Qmv3F1JLR1DFHrUrGDD2fMKWaHXiF2miu0JIAHax-roCaD5dAJI4A16PN-RdZG0xIlmNhSD3LIpm8fLS3FNqSA9x=w935-h456-s-rw-gm" alt="PHPMailer + Gmail OAuth 寄信 13" style="width:600px" title="PHPMailer + Gmail OAuth2 寄信"></figure></div>


<p>應用程式類型選擇「網頁應用程式」，名稱為必填，可以跟小蛙一樣輸入 PHPMailer，只要能辨識即可。「已授權的重新導向 URI」填入網站下 phpmailer 套件下的 <code>get_oauth_token.php</code> 路徑 (也可以把它拉出來到外層比較好處理的地方)，小蛙這邊的例子是 </p>



<pre class="wp-block-preformatted">https://xx.xxx/vendor/phpmailer/phpmailer/get_oauth_token.php</pre>


<div class="wp-block-image">
<figure class="aligncenter is-resized"><img decoding="async" src="https://lh3.googleusercontent.com/pw/AP1GczOvK99odz0V_ok4Ie8wEihuHHv3Xd3nohjEQ1SmNSN1I50Ee6aQvGsCmfK7gHRbfmJ5ZcSVeeErcTpRocoGuWztkqtHUyZt1oilrTZdcgLYnkeM8e4ZMt7Am8nv05r2prtZfGseGj2stkKXgvBz7dgz=w681-h993-s-rw-gm" alt="PHPMailer + Gmail OAuth 寄信 14" style="width:503px" title="PHPMailer + Gmail OAuth2 寄信"></figure></div>


<p>建立完成後會得到<strong><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">用戶端編號</mark></strong>及<mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color"><strong>用戶端密鑰</strong></mark>，先存起來等一下馬上會用到。</p>


<div class="wp-block-image">
<figure class="aligncenter is-resized"><img decoding="async" src="https://lh3.googleusercontent.com/pw/AP1GczPcJ7LUPlQ7amLYg7ihWiFq4zwGti6hcZPBNouXbgkQ_tRXUQmQ9CrD9mPV_-LsRN2wybLy7tyxGnXAI0ndlSzMC1TGMR3QuT8TNQYwXeBn6HTxwvEE_J_U_vmVtEymVD4jh9EnFf4UYMtweBlLZ2K1=w570-h480-s-rw-gm" alt="PHPMailer + Gmail OAuth 寄信 15" style="width:400px" title="PHPMailer + Gmail OAuth2 寄信"></figure></div>


<h2 class="wp-block-heading para">取得 Refresh Token</h2>



<p>找到 PHPMailer 下的 <code>get_oauth_token.php</code> (預設應該會在網頁目錄下的 <code>vender/phpmailer/phpmailer/</code>)，PHPMailer 原始附帶的檔案會一直卡在 Provider missing 或 Invalid state，沒辦法正確取得 Refresh Token，因此小蛙對 <code>get_oauth_token.php</code> 做了一些修改，確保可以拿到 token。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="php" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">&lt;?php
/**
 * PHPMailer - PHP email creation and transport class.
 * PHP Version 5.5
 * @package PHPMailer
 * @see https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project
 * @author Marcus Bointon (Synchro/coolbru) &lt;phpmailer@synchromedia.co.uk>
 * @author Jim Jagielski (jimjag) &lt;jimjag@gmail.com>
 * @author Andy Prevost (codeworxtech) &lt;codeworxtech@users.sourceforge.net>
 * @author Brent R. Matzelle (original founder)
 * @copyright 2012 - 2020 Marcus Bointon
 * @copyright 2010 - 2012 Jim Jagielski
 * @copyright 2004 - 2009 Andy Prevost
 * @license https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html GNU Lesser General Public License
 * @note This program is distributed in the hope that it will be useful - WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.
 */

/**
 * Get an OAuth2 token from an OAuth2 provider.
 * * Install this script on your server so that it's accessible
 * as [https/http]://&lt;yourdomain>/&lt;folder>/get_oauth_token.php
 * e.g.: http://localhost/phpmailer/get_oauth_token.php
 * * Ensure dependencies are installed with 'composer install'
 * * Set up an app in your Google/Yahoo/Microsoft account
 * * Set the script address as the app's redirect URL
 * If no refresh token is obtained when running this file,
 * revoke access to your app and run the script again.
 */

namespace PHPMailer\PHPMailer;

// 用來看錯誤訊息以及刪除 opcache
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
@opcache_reset();
	
/**
 * Aliases for League Provider Classes
 * Make sure you have added these to your composer.json and run `composer install`
 * Plenty to choose from here:
 * @see https://oauth2-client.thephpleague.com/providers/thirdparty/
 */
//@see https://github.com/thephpleague/oauth2-google
use League\OAuth2\Client\Provider\Google;

// 根據自己的 vendor 路徑進行調整
require '../../autoload.php';

session_start();

// 改成剛剛在 Google Cloud 上設定的值
$providerName = 'Google';
// 用戶端編號
$clientId = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com';
// 用戶端密碼
$clientSecret = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX';
// 已授權的重新導向 URI
$redirectUri = 'https://xxx.xxxx.xxx/get_oauth_token.php';

$_SESSION['provider'] = $providerName;
$_SESSION['clientId'] = $clientId;
$_SESSION['clientSecret'] = $clientSecret;

$params = [
    'clientId' => $clientId,
    'clientSecret' => $clientSecret,
    'redirectUri' => $redirectUri,
    'accessType' => 'offline'
];

$options = [];
$provider = null;

switch ($providerName) {
    case 'Google':
        $provider = new Google($params);
        $options = [
            'scope' => [
                'https://mail.google.com/'
            ]
        ];
        break;
}

if (null === $provider) {
    exit('Provider missing');
}

if (!isset($_GET['code'])) {
    //If we don't have an authorization code then get one
    $authUrl = $provider->getAuthorizationUrl($options);
    $_SESSION['oauth2state'] = $provider->getState();
    header('Location: ' . $authUrl);
    exit;
    //Check given state against previously stored one to mitigate CSRF attack
	// 這段不註解掉的話，會一直卡在 Invalid state，沒辦法拿到正確的 token
/*} elseif (empty($_GET['state']) || ($_GET['state'] !== $_SESSION['oauth2state'])) {
	error_log("3333");
	error_log("state 3333 " . $_SESSION['oauth2state']);
    //unset($_SESSION['oauth2state']);
    //unset($_SESSION['provider']);
    exit('Invalid state');*/
} else {
    //unset($_SESSION['provider']);
    //Try to get an access token (using the authorization code grant)
    $token = $provider->getAccessToken(
        'authorization_code',
        [
            'code' => $_GET['code']
        ]
    );
    //Use this to interact with an API on the users behalf
    //Use this to get a new access token if the old one expires
    echo 'Refresh Token: ', htmlspecialchars($token->getRefreshToken());
}</pre>



<p>將內容貼上後，開啟瀏覽器連到該網址 (就是<strong>已授權的重新導向 URI)</strong> 開始進入 OAuth 登入流程，選擇要登入的帳號</p>


<div class="wp-block-image">
<figure class="aligncenter is-resized"><img decoding="async" src="https://lh3.googleusercontent.com/pw/AP1GczNd2HKRgMmOhBQaMmcC9pgUefAAsic1hkMqQzNHntO-1WCADxGh2gI74MXUtCztrElVXrZnqGeFwdlhg_Wu_VqUPq8esg9tm6kbcFcFJ6ixXkpRNfY7_t6sFZkMkzJBqqt9NtKBjoHpawuXktXa34LZ=w1058-h401-s-rw-gm" alt="PHPMailer + Gmail OAuth 寄信 16" style="width:700px" title="PHPMailer + Gmail OAuth2 寄信"></figure></div>


<p>確認登入</p>


<div class="wp-block-image">
<figure class="aligncenter is-resized"><img decoding="async" src="https://lh3.googleusercontent.com/pw/AP1GczNyIy5svb1IInWm1pj7vJurWmbOEW6vM4LNL0JxtFFqilMaB_mu_PT3WV-MMYfXhKIDG99pTDOlE9fOKxFH8Z4MUhbM-E-bWcSaOt5cJ3hoNDTeWIut3PJ3g-TgfLLJZNkOiyQjGLX6-Yr4VXKBW7sh=w1063-h490-s-rw-gm" alt="PHPMailer + Gmail OAuth 寄信 17" style="width:700px" title="PHPMailer + Gmail OAuth2 寄信"></figure></div>


<p>信任應用程式</p>


<div class="wp-block-image">
<figure class="aligncenter is-resized"><img decoding="async" src="https://lh3.googleusercontent.com/pw/AP1GczOW1-cRB-uxqhR9v7znPOoAw006Lx3tuBqFpba4WSijsidXKh0hKuWr1kvTz7KYfo0n38zK11rLkHPdvRNdOIqcpKiQcYfUz3zLxmJomAcC5j_gg2zUM8-yvCaGCw4EWqImteEhvYos6aLjoRAoojr2=w1057-h699-s-rw-gm" alt="PHPMailer + Gmail OAuth 寄信 18" style="width:700px" title="PHPMailer + Gmail OAuth2 寄信"></figure></div>


<p>最後會印出 Refresh Token: xxxxxxxxxx，這個 token 一定要存好，少了這個 PHPMailer 就沒辦法透過 OAuth 驗證寄信喔，原本以為 <code>get_oauth_token.php</code> 每次執行應該 &#8220;有機會&#8221; 去換一個可使用的 Token 回來，不過再執行一次會發現 Refresh Token: 變成空白。</p>


<div class="wp-block-image">
<figure class="aligncenter"><img decoding="async" src="https://lh3.googleusercontent.com/pw/AP1GczMAEzc9EkM0XaVMs8px7YKL3EXAUJ2L_uJ8YlSTBBnEJAP8BH4JqC2s_b5_Rm1LNffiyRiTBmehd0jhvLbPhpAslSkq-8Lx1BfxwSTfg1jLVcAgOcadwiOl_V0YmZzKy86GplsW1NK61FBz9sCKGyCH=w861-h72-s-rw-gm" alt="AP1GczMAEzc9EkM0XaVMs8px7YKL3EXAUJ2L uJ8YlSTBBnEJAP8BH4JqC2s b5 Rm1LNffiyRiTBmehd0jhvLbPhpAslSkq 8Lx1BfxwSTfg1jLVcAgOcadwiOl V0YmZzKy86GplsW1NK61FBz9sCKGyCH=w861 h72 s rw gm PHPMailer + Gmail OAuth2 寄信" title="PHPMailer + Gmail OAuth2 寄信"></figure></div>


<p>到這邊就成功取得可以使用的 Token 了，回到 PHPMailer 寄信程式吧！</p>



<h2 class="wp-block-heading para">使用 PHPMailer 寄信</h2>



<p>複製下面的檔案，視自身情況修改幾個地方：</p>



<ol class="my-li bg-darkblue wp-block-list">
<li><strong>require(&#8216;./vendor/autoload.php&#8217;);</strong>：將位置指向正確的路徑。</li>



<li><strong>$client_id</strong>：前面步驟取得的用戶端編號。</li>



<li><strong>$client_secret</strong>：前面步驟取得的用戶端密碼。</li>



<li><strong>$refresh_token</strong>：前面步驟取得的 Token。</li>



<li><strong>$email</strong>：前面步驟通過 OAuth 的信箱。</li>



<li>信件相關之寄件人、收件人、主旨、內容 &#8230; 等。</li>
</ol>



<pre class="EnlighterJSRAW" data-enlighter-language="php" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">&lt;?php

// 用來看錯誤訊息以及刪除 opcache
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
@opcache_reset();

// 根據自己的路徑修改 composer 的載入位置
require('./vendor/autoload.php');

use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;
use PHPMailer\PHPMailer\OAuth;
use League\OAuth2\Client\Provider\Google;

// 用戶端編號
$client_id 	= 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com';
// 用戶端密碼
$client_secret 	= 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
// 從前一個步驟取得的 Token
$refresh_token  = '1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxg';
// OAuth 的信箱
$email		= 'xxxxxxx@xxxxxxx';

$mail = new PHPMailer(true);

$provider = new Google(
	[
		'clientId' => $client_id,
		'clientSecret' => $client_secret,
	]
);

$mail->setOAuth(
	new OAuth(
		[
			'provider'     => $provider,
			'clientId'     => $client_id,
			'clientSecret' => $client_secret,
			'refreshToken' => $refresh_token,
			'userName'     => $email,
		]
	)
);

$mail->isSMTP();

$mail->SMTPDebug 	= 3;				// 如果需要顯示debug內容,測完確定沒問題請改成 0
$mail->SMTPAuth 	= true; 
$mail->SMTPSecure 	= 'tls';
$mail->AuthType 	= 'XOAUTH2';
$mail->Host 		= "smtp.gmail.com";
$mail->Port 		= 587;
$mail->CharSet 		= "utf-8";

$mail->setFrom('寄件人信箱', '寄件人名稱');    // 寄件人
$mail->addAddress('收件人信箱', '收件人名稱'); // 收件人
$mail->isHTML(true);                         // 寄送 HTML 格式郵件

$mail->Subject = "郵件主旨";                  // 主旨
$mail->Body    = "&lt;Strong>測試&lt;/Strong>";     // 信件內容
$mail->AltBody = "測試";                      // 無法顯示 HTML 時的內容

$mail->send();

?></pre>



<p>一切就緒後連到該寄信的 PHP 頁面，就可以成功把信寄出囉！</p>


<div class="wp-block-image">
<figure class="aligncenter is-resized"><img decoding="async" src="https://lh3.googleusercontent.com/pw/AP1GczMLz2nu2nJ4oC9XUvFKUNbJNFysGsEQYN9LUHzuBmiEiyxnq5avpPb8-nMINhWVug9WD-guXHdUyfrte1yUxdbLU9O4rRn0fxZZ59U1vF0-j_1XofQvqYgfIHzmGwr-hf9y1ccy9TBervTm_5lZ7Y6w=w630-h363-s-rw-gm" alt="PHPMailer + Gmail OAuth 寄信 19" style="width:400px" title="PHPMailer + Gmail OAuth2 寄信"></figure></div>


<pre class="wp-block-preformatted">延伸閱讀：<a href="https://noter.tw/10744/google-%e8%a9%a6%e7%ae%97%e8%a1%a8%e6%89%b9%e9%87%8f%e7%99%bc%e9%80%81-email-yamm/" data-wpel-link="internal">Google 試算表批量發送 Email (免費版每日 50 封)</a></pre>
<p>這篇文章 <a rel="nofollow" href="https://noter.tw/12780/phpmailer-gmail-oauth2-%e5%af%84%e4%bf%a1/" data-wpel-link="internal">PHPMailer + Gmail OAuth2 寄信</a> 最早出現於 <a rel="nofollow" href="https://noter.tw" data-wpel-link="internal">記下來</a>。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://noter.tw/12780/phpmailer-gmail-oauth2-%e5%af%84%e4%bf%a1/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
