前言 #
本篇主要介紹如何實作 Google OAuth 第三方登入,下面的實作是基於現有的會員系統上整合第三方登入,關於之前的會員登入系統部分可以參考這篇:《Docker 部署 Spring Boot + Vue + PostgreSQL 實現一個會員註冊登入系統》。有鑒於那篇真的太冗長了,本編將 著重於 Google OAuth 的設定 。
- 使用者的透過 Google 帳號登入註冊流程非常簡單,流程如下:
- 進到登入畫面,選擇
使用 Google 帳戶登入。
- 選擇登入的 Google 帳號。

- 並允許個人資料授權。

- 系統就會綁定 Google 帳號進行登入。

Google OAuth 整合流程 #
在下方的流程圖中,簡單說明了用戶從點擊 Google 登入按鈕,到最終登入成功的整個流程。這個流程包含 前端初始化 Google 登入、用戶授權、後端驗證 ID Token、查詢或創建用戶資料,並最終回傳 JWT Token 給前端,完成登入。整個過程大致如下:
系統實作 #
Google OAuth 設定 #
- 前往 Google Cloud Console
- 展開側邊欄點選
API和服務,選擇OAuth 同意畫面。
- 輸入
應用程式名稱、使用者支援電子郵件。
這裡填寫的郵件,會顯示在開發人員資訊上

- 選擇
外部目標對象。
- 填寫負責人員的電子郵件地址。

- 同意 Google API 條款。

- 按下建立後會出現
OAuth 總覽, 點擊建立 OAuth 用戶端
- 選擇
網頁應用程式類型。
- 填入
名稱,以及JavaScripte來源、重新導向URL。 測試網址填入:http://localhost ,到時候有了正式網域後再添加上去。
- 按下
建立後,就會得到用戶端ID、用戶端密碼
前端實作 #
前端 Vue 頁面需要整合 Google Identity Services,前端只需要處理回調,複雜的驗證邏輯交給 Google,實作的部分,主要包含三個步驟:
1. 初始化 Google Identity Services #
動態載入 Google Identity Services 的 JavaScript 函式庫,確保在需要時才載入,避免影響頁面初始載入速度,只有當用戶真的想用 Google 登入時才載入相關資源。
- 範例程式碼
// 載入 Google Identity Services 腳本
const loadGoogleScript = (): Promise<void> => {
return new Promise((resolve, reject) => {
if (window.google) {
resolve()
return
}
const script = document.createElement('script')
script.src = 'https://accounts.google.com/gsi/client'
script.async = true
script.defer = true
script.onload = () => resolve()
script.onerror = () => reject(new Error('Failed to load Google script'))
document.head.appendChild(script)
})
}2. 初始化 Google Sign-In #
這裡只需要前面在 Google Cloud Console 上取得的 用戶端ID 帶到 YOUR_GOOGLE_CLIENT_ID。設定好後,Google 就會自動幫我們渲染出登入按鈕,而且會根據用戶的語言環境自動調整顯示文字。
- 範例程式碼
// 初始化 Google Sign-In
onMounted(async () => {
await loadGoogleScript()
if (window.google) {
window.google.accounts.id.initialize({
client_id: 'YOUR_GOOGLE_CLIENT_ID',
callback: handleGoogleCallback,
auto_select: false,
cancel_on_tap_outside: true,
context: 'signin'
})
// 渲染 Google 登入按鈕
const buttonContainer = document.getElementById('google-signin-button')
if (buttonContainer) {
window.google.accounts.id.renderButton(buttonContainer, {
theme: 'outline',
size: 'large',
text: 'signin_with',
shape: 'rectangular',
width: '100%'
})
}
}
})3. Google 登入回調處理 #
當用戶完成 Google 授權後,會收到包含 credential 的回調,這個 credential 就是 Google 給我們的 ID Token。
credential 是一個 JWT (JSON Web Token) 格式的字串,包含以下欄位:
sub:Google 用戶的唯一 ID(來源:Google 帳號系統)email:用戶的 Google 信箱(來源:Google 帳號資料)name:用戶的顯示名稱(來源:Google 個人資料)picture:用戶的頭像 URL(來源:Google 個人資料)email_verified:信箱是否已驗證(來源:Google 驗證狀態)aud:Client ID(用於驗證,來源:Google Cloud Console 設定)iss:發行者(固定為 “https://accounts.google.com”)exp:Token 過期時間(來源:Google 自動生成)iat:Token 發行時間(來源:Google 自動生成)azp:授權方(Client ID,來源:Google Cloud Console 設定)
格式文件參考:
我們把這個 ID Token 發送給後端,後端會向 Google 的 tokeninfo API 驗證這個 Token 是否有效,Google 會回傳用戶的詳細資訊。後端拿到這些資訊後,會檢查用戶是否已存在,如果 不存在就創建新用戶,最後回傳我們系統的 JWT Token 給前端,整個流程就完成了。
- 範例程式碼
// Google 登入回調處理
const handleGoogleCallback = async (response: any) => {
const result = await fetch('/api/auth/google-login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ idToken: response.credential })
})
const data = await result.json()
if (result.ok && data.success) {
AuthUtils.setAuth(data.token, data.refreshToken, data.user, true)
router.push('/')
}
}後端實作 #
後端主要接收的 API:
POST /api/auth/google-login:接收前端傳來的 Google ID Token- Service 的部分建立
GoogleOAuthService來處理 Google Token 驗證
實作主要包含三個核心功能:
1. Google Token 驗證 #
後端接收到前端傳來的 Google ID Token 後,會向 Google 的 tokeninfo API 發送驗證請求,獲取用戶資訊並驗證 Token 的有效性。
String url = "https://oauth2.googleapis.com/tokeninfo?id_token=" + idToken;
ResponseEntity<Map> response = restTemplate.getForEntity(url, Map.class);同時檢查 audience 欄位確保 Token 是為我們的應用程式發行的,防止偽造攻擊。
// 驗證 audience (client ID)
Map<String, Object> userInfo = (Map<String, Object>) response.getBody();
String audience = (String) userInfo.get("aud");
if (!clientId.equals(audience)) {
result.put("success", false);
result.put("message", "無效的 Google Token");
return result;
}
String googleId = (String) userInfo.get("sub");
String email = (String) userInfo.get("email");
String name = (String) userInfo.get("name");
String picture = (String) userInfo.get("picture");
Object emailVerifiedObj = userInfo.get("email_verified");2. 用戶管理與綁定 #
當用戶透過 Google 登入時,會先檢查是否已有對應的 Google 用戶記錄。如果找到就直接登入。 如果沒有找到,系統會嘗試透過電子郵件查找現有的系統用戶:
- 該
電子郵件已經註冊過,就會將 Google 帳號綁定到現有用戶。 沒有註冊過的新用戶,系統會自動創建新的用戶記錄,並標記為 Google 用戶。
findByEmail透過 Google 帳號的電子郵件地址查找現有的系統用戶。這個方法主要處理現有系統用戶綁定 Google 登入的情況,當系統發現該電子郵件已經在系統中註冊過,就會將 Google 帳號資訊綁定到現有用戶。
一般註冊用戶
一般用戶是透過帳號密碼進行登入的,所以擁有修改密碼的功能。

Google註冊用戶
透過 Google 進行綁定登入的用戶,直接透過 Google 驗證做登入,就不需要修改密碼的功能了。
綁定Google帳戶 後,就無法再透過一般帳密做登入了,
驗證登入交給 Google,對於系統面的考量來說安全性也較高。

3. JWT Token 生成 #
驗證成功後生成系統的 JWT Token 和 Refresh Token,並將用戶資訊回傳給前端,確保 Google 登入用戶與一般用戶享有相同的驗證 Token。
資料庫調整 #
在之前的會員 users 表中新增 Google OAuth 相關欄位:
google_id:Google 使用者 IDgoogle_email:Google 帳號電子郵件is_google_user:是否為 Google 註冊用戶google_picture_url:Google 帳號頭像 URL
並建立相應的索引和查詢方法來支援 Google 用戶的查找和綁定。
結語 #
透過整合 Google OAuth,成功實現了第三方登入功能,大幅提升了用戶註冊登入的便利性,可直接使用現有的 Google 帳號登入,簡單又方便的註冊管道,可提高顧客加入會員的意願,同時也能減少忘記密碼等問題。