全端勇士之路 Node.js-OAuth 2.0 & nodemailer & Gmail

前言

這一次來針對 nodemailer 多一個介紹,因為現在 Google 已經不再接受使用帳號密碼的形式去發送 Gmail 信件,所以就紀錄一下,如何使用 Express + OAuth 2.0 + nodemailer + Gmail 的筆記。

原因

在原本的章節 nodemailer 設置上是這樣子

1
2
3
4
5
6
7
8
9
var transporter = nodemailer.createTransport({
service: 'Gmail'
host: "smtp.ethereal.email",
port: 587,
auth: { // 要用來發信的帳號及密碼,後面可以改用 dotenv 來傳入,進而保護自己的帳密
user: 'XXX@gmail.com',
pass: 'Paswword'
}
});

但是在現階段由於 Google 更改了認證方式,所以不在接受使用帳號密碼登入,所以會出現以下錯誤訊息

1
535-5.7.8 Username and Password not accepted. Learn more at\n535 5.7.8  https://support.google.com/mail/?p=BadCredentials d5sm35056162pfd.107 - gsmtp

在原本的 nodemailer 官方也有聲明建議改使用 OAuth2 來使用,所以這一篇就來補充一下該如何使用 OAuth 發送 Gmail 信箱吧。

第一步驟 建立 OAuth

首先我們要先到 Google Cloud Platform 建立一個新專案

左上建立一個新專案

專案這邊隨意取名就好,我取名為 Gmail Test

Gmail Test

接下來點一下側邊欄位,可以看到 API 和服務

API 和服務

到達 API 和服務的頁面後點一下上方 啟用 API 和服務

啟用 API 和服務

接著搜尋 Gmail API,點進去 啟用

Gmail API

啟用

啟用 Gmail API 之後點旁邊 憑證建立憑證OAuth 用戶端 ID

OAuth 用戶端 ID

這個時候應該會看到 Google 會要求你「您必須先在同意畫面中設定產品名稱,才能建立 OAuth 用戶端 ID」,就點進去設定,接下來這邊要注意一下「User Type」請選擇 外部

User Type

接下來填寫應用程式名稱使用者支援電子郵件開發人員聯絡資訊就可以送出(反正只是測試用而已),後面不用太在意只需要持續按下儲存與繼續即可。

OAuth 同意畫面

這邊有一個重點,在後來的 Google OAuth 必須新增測試使用者,因此在第三步驟的「測試使用者」時,必須填入要測試用的使用者帳號(Google 帳號),這邊請務必使用你即將用於 Node.js 的帳號,而不是隨便新增的帳號。

測試使用者

如果你沒有新增測試使用者的話,稍後的流程你會得到這個畫面。

Error 403: access_denied

接下來一樣回到 憑證建立憑證OAuth 用戶端 ID

OAuth 用戶端 ID

這邊選擇時,請注意選擇「網路應用程式」而不是電腦應用程式、Chrome 應用程式等等,如果你選網路應用程式之外的選項就無法繼續下去囉。

網路應用程式

接下來請在下方「已授權的重新導向 URI」選擇「新增 URL」,這邊欄位「https://developers.google.com/oauthplayground」,請不要填「https://developers.google.com/oauthplayground/」,你絕對會無法驗證。

已授權的重新導向 URI

最後你就取得 Client ID 以及 Client Secret ,請保存著,稍後會使用到。

Client ID 以及 Client Secret

第二步驟 - 取得 Refresh token 與 Access token

接下來請開啟這個網址 https://developers.google.com/oauthplayground,然後點一下右上齒輪,並將「Use your own OAuth credentials」打勾輸入剛剛的 Client ID 以及 Client Secret

Client ID 以及 Client Secret

然後左邊輸入框輸入「https://mail.google.com/」或者找一下「Gmail API V1」然後選 https://mail.google.com/ 並按下 Authorize APIs

Authorize APIs

當你按下 Authorize APIs 會跳到你很熟悉的畫面,如果你有多個帳號,請選擇相對應帳號

請選擇相對應帳號

看到這個畫面稍微有點恐怖,但不用擔心,這是我們自己的應用程式所以沒關係

這個應用程式未經 Google 驗證

Google 對於使用者的權限非常注重,所以會再問你一次

使用者的權限

oh…看吧,Google 真的很注重你的帳號安全

使用者的權限

這時候你會發現我們跳回原本的畫面,這邊就按一下「Exchange authorization code for tokens」

Exchange authorization code for tokens

此時你就會取得 Access token 以及 Refresh token,這兩者都麻煩記下來。

第三步驟 - 修改 nodemailer

最後回到我們先前的專案中,在前面有提到原本是採用一般帳號密碼的方式登入並使用 nodemailer 的服務,所以我們這邊要稍微調整一下,基本上就是將前面的 clientIdclientSecret 以及 refreshToken 改用環境變數傳入並將程式碼改成以下即可

1
2
3
4
5
6
7
8
9
10
11
12
13
const transporter = nodemailer.createTransport({
host: 'smtp.gmail.com',
port: 465,
secure: true,
auth: {
type: "OAuth2",
user: process.env.ACCOUNT,
clientId: process.env.CLINENTID,
clientSecret: process.env.CLINENTSECRET,
refreshToken: process.env.REFRESHTOKEN,
accessToken: process.env.ACCESSTOKEN,
}
});

env 的部分若不清楚可以回顧這一篇

恭喜你完成了使用 OAuth 發送 nodemailer。

最後一樣附上Heroku 測試站

參考文獻

Liker 按讚 (拍手)

如果這一篇筆記文章對你有幫助,希望可以求點牡蠣鼓勵 (ノД`)・゜・。

Liker 是一個按讚(拍手)機制,一個人一篇文章最多只能按五下拍手,如果你願意按個讚,對於創作者是一個莫大的鼓勵。

Google AD