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

前言

這一次來針對 nodemailer 多一個介紹,因為現在 Google 已經不再接受使用一般的帳號密碼去做發送信件動作,所以就來寫一篇 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 用戶端 ID,然後請選擇 網路應用程式 並填入 已授權的重新導向 URI

這邊有一個重點要注意 已授權的重新導向 URI 請填 「https://developers.google.com/oauthplayground」,請不要填「https://developers.google.com/oauthplayground/」,你絕對會無法驗證。

網路應用程式

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

Client ID 以及 Client Secret

第二步驟 - 取得 Refresh token

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

Client ID 以及 Client Secret

然後左邊輸入框輸入「https://mail.google.com/」並按下 Authorize APIs

Authorize APIs

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

請選擇相對應帳號

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

警告畫面

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

使用者的權限

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

使用者的權限

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

Exchange authorization code for tokens

此時你就會取得 Access token 以及 Refresh token,但是我們這邊只記下 Refresh token 就好

第三步驟 - 修改 nodemailer

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

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

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

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

最後一樣附上Heroku 測試站

參考文獻

0%