一、今日學習目標
第十一天已經完成 Google Cloud 專案設定、啟用 Google Calendar API、建立 OAuth 2.0 憑證,並使用 Node.js 成功讀取 credentials.json。但程式成功讀取憑證不代表程式已經獲得存取 Google Calendar 的權限。還需要建立 OAuth 2.0 用戶端物件(OAuth2Client),讓程式能利用憑證中的設定,為後續的 Google 帳號授權流程做準備。
今日重點:
二、實作過程
discord-calendarBot/
├── node_modules/
├── src/
│ ├── commands/
│ │ ├── add.js
│ │ └── help.js
│ ├── googleAuth.js
│ └── index.js
├── .env
├── .gitignore
├── credentials.json
├── deploy-commands.js
├── package.json
└── README.md
其中:
credentials.json:儲存從 Google Cloud 下載的 OAuth 用戶端設定
googleAuth.js:負責 Google OAuth 授權相關程式
index.js:Discord Bot 的主要執行程式
將 OAuth 相關功能獨立放在 googleAuth.js,可以避免所有功能集中在 index.js,讓後續程式碼更容易維護。
const { google } = require("googleapis");
const fs = require("fs");
const path = require("path");
const CREDENTIALS_PATH = path.join(__dirname, "../credentials.json");
const credentials = JSON.parse(
fs.readFileSync(CREDENTIALS_PATH, "utf8")
);
console.log("Google OAuth 憑證讀取成功");
console.log("用戶端類型:", credentials.installed ? "Desktop" : "其他");
這段程式主要完成三件事。
第一,取得憑證檔案的位置。
const CREDENTIALS_PATH = path.join(__dirname, "../credentials.json");
__dirname 代表目前 JavaScript 檔案所在的資料夾。
由於 googleAuth.js 位於 src,而 credentials.json 位於專案根目錄,因此需要使用 ../ 回到上一層資料夾。
第二,讀取並解析 JSON。
const credentials = JSON.parse(
fs.readFileSync(CREDENTIALS_PATH, "utf8")
);
fs.readFileSync() 將憑證檔案讀取為文字,再透過 JSON.parse() 轉換成 JavaScript 物件,讓程式可以取得其中的設定值。
第三,確認用戶端類型。
credentials.installed ? "Desktop" : "其他"
Google Desktop 應用程式類型的 OAuth JSON,通常會將用戶端設定放在 installed 欄位內。
這裡利用條件運算子確認是否存在該欄位。
但目前為止,我們只是成功讀取設定資料,還沒有真正建立用來進行授權的 OAuth 用戶端。
const { client_id, client_secret, redirect_uris } = credentials.installed;
這裡使用 JavaScript 的解構賦值(Destructuring Assignment),一次取得 credentials.installed 物件內的三個屬性。
三個設定分別代表:
client_id: OAuth 用戶端識別碼,用來讓 Google 辨識是哪一個應用程式提出授權請求。
client_secret: OAuth 用戶端的憑證資訊之一。
redirect_uris:授權完成後使用的重新導向 URI 設定。
需要注意的是,Desktop App 屬於公開用戶端(Public Client),因此不能依賴 client_secret 來證明應用程式身分,也不能將它當成使用者的 Google 密碼。
正式進行 Desktop App 授權時,仍需要確認回呼 URI 符合 Google 的本機授權流程要求。
const oauth2Client = new google.auth.OAuth2(
client_id,
client_secret,
redirect_uris[0]
);
console.log("OAuth 2.0 用戶端建立成功");
google.auth.OAuth2 是 googleapis 套件提供的 OAuth 2.0 用戶端類別。
使用 new 建立物件後,程式就能透過這個物件執行後續的授權相關操作。
例如:
產生 Google 授權網址
使用授權碼交換 Token
設定 API 呼叫所需的憑證
配合有效的 Refresh Token 更新 Access Token
但是建立 OAuth2Client 物件不等於完成 Google 帳號授權。
目前只是準備好執行授權流程所需的程式物件,還沒有取得 Access Token,因此也尚未具備存取私人 Google Calendar 資料的權限。
今天的 src/googleAuth.js 完整內容如下:
const { google } = require("googleapis");
const fs = require("fs");
const path = require("path");
// 設定 OAuth 憑證檔案路徑
const CREDENTIALS_PATH = path.join(__dirname, "../credentials.json");
// 讀取 OAuth 憑證
const credentials = JSON.parse(
fs.readFileSync(CREDENTIALS_PATH, "utf8")
);
console.log("Google OAuth 憑證讀取成功");
console.log("用戶端類型:", credentials.installed ? "Desktop" : "其他");
// 取得 OAuth 2.0 用戶端設定
const { client_id, client_secret, redirect_uris } = credentials.installed;
// 建立 OAuth 2.0 用戶端物件
const oauth2Client = new google.auth.OAuth2(
client_id,
client_secret,
redirect_uris[0]
);
console.log("OAuth 2.0 用戶端建立成功");
在 VS Code 終端機輸入:node src/googleAuth.js
Google OAuth 憑證讀取成功
用戶端類型: Desktop
OAuth 2.0 用戶端建立成功
這代表:
Node.js 成功讀取 credentials.json
JSON 檔案包含 Desktop 類型的 OAuth 設定
程式成功建立 OAuth2Client 物件
但測試結果並不代表 Google 已經授權,也不代表 Calendar API 已經成功連線。
三、今日學習重點
今天最重要的是理解 credentials.json 與 OAuth2Client 的關係。
credentials.json 是 Google Cloud 提供的 OAuth 用戶端設定資料,而 OAuth2Client 是 Node.js 程式利用這些設定建立的物件。
整體流程如下:
Google Cloud
↓
下載 credentials.json
↓
Node.js 讀取 JSON
↓
取得 client_id、client_secret、redirect_uris
↓
建立 OAuth2Client
↓
準備執行 Google OAuth 授權流程
為什麼不能只讀取 JSON 就直接操作 Google Calendar?
因為 OAuth 2.0 將應用程式識別與使用者授權分開處理。
即使 Google 能辨識應用程式,也不代表使用者已同意讓它存取自己的日曆。
因此,後續仍然需要取得使用者授權,並透過 Access Token 存取 Google Calendar API。
另外,credentials.json 包含應用程式的憑證資訊,應避免上傳到公開的 GitHub Repository,並透過 .gitignore 排除。