OAuth 2.0 如何運作:開發者指南(2026)

OAuth 2.0 是「使用 Google 登入」與各大 API 背後的標準。本文用圖解與程式碼完整說明其運作方式。

OAuth 2.0 如何運作:開發者指南(2026)

每次你按下「使用 Google 登入」,或把第三方 App 連到你的 GitHub 帳號,背後都在跑 OAuth 2.0。它是一個協定,讓使用者可以授權 App 存取自己的資料,而不需要交出密碼。

這篇指南會帶你完整理解 OAuth 2.0 如何運作:逐步拆解授權流程、說明各種 grant type 的用途、比較它與 OIDC、JWT 的差別,以及各自的使用時機。

什麼是 OAuth 2.0?

OAuth 2.0 是一個開放式授權框架,讓使用者可以把自己在某個服務上的帳號,授予第三方應用程式有限存取權限——而不需要分享密碼。

你可以把它想像成飯店房卡系統。你不會把通行密鑰(密碼)交給房客;飯店(授權伺服器)會發一張有時效、只能開特定門(scope)的房卡(access token)。

OAuth 2.0 是 授權(authorization),不是驗證(authentication)。它回答的是「這個 App 可以存取什麼?」而不是「這個使用者是誰?」(後者由 OpenID Connect 在 OAuth 之上補齊。)

OAuth 2.0 的四個角色

在看流程之前,先認識參與的四方角色:

角色 說明 範例
Resource Owner 擁有資料的使用者 你(正在登入的人)
Client 發出存取請求的應用程式 想讀取你 Google Calendar 的待辦 App
Authorization Server 在使用者同意後簽發 token Google 的 OAuth 伺服器(accounts.google.com)
Resource Server 託管受保護資料的伺服器 Google Calendar API

OAuth 2.0 授權碼流程:逐步解析

最常見也最安全的 OAuth 2.0 流程是 Authorization Code flow。以下是它一步步發生的事:

Step 1: Client 將使用者導向 Authorization Server

流程從使用者點下「使用 Google 登入」(或類似按鈕)開始。Client 會把使用者導向授權伺服器,URL 類似:


https://accounts.google.com/o/oauth2/v2/auth?
  client_id=YOUR_CLIENT_ID
  &redirect_uri=https://yourapp.com/callback
  &response_type=code
  &scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcalendar.readonly
  &state=random_csrf_token
  &code_challenge=BASE64URL(SHA256(code_verifier))
  &code_challenge_method=S256

關鍵參數:

  • client_id — 向授權伺服器識別你的應用程式
  • redirect_uri — 使用者同意後要被導回的位置
  • scope — 你請求的權限範圍(例如 calendar.readonly)。注意:若在 scope 加上 openid,就會在 OAuth 2.0 上啟用 OpenID Connect,適合你同時需要識別使用者時。
  • state — 用來防止 CSRF 攻擊的隨機值
  • code_challengePKCE 擴充的一部分(public client 必備)

Step 2: 使用者登入並同意授權

授權伺服器會顯示登入頁與同意畫面——例如「此 App 想存取你的電子郵件與個人資料,是否允許?」——使用者可選擇允許或拒絕。

Step 3: Authorization Server 回傳授權碼

使用者同意後,授權伺服器會導回你的 redirect_uri,並附上一個短時效 authorization code:


https://yourapp.com/callback?code=AUTH_CODE_HERE&state=random_csrf_token

這個 code 是暫時性的(通常 60–120 秒過期)且只能使用一次。它不是 access token——你的伺服器仍需將它交換成 token。

Step 4: Client 以授權碼交換 Access Token

你的伺服器會對 token endpoint 發出後端 POST 請求——這在 server-side 進行,因此 client secret 不會暴露在瀏覽器:


const response = await fetch('https://oauth2.googleapis.com/token', {
  method: 'POST',
  headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
  body: new URLSearchParams({
    grant_type: 'authorization_code',
    code: 'AUTH_CODE_HERE',
    redirect_uri: 'https://yourapp.com/callback',
    client_id: process.env.CLIENT_ID,
    client_secret: process.env.CLIENT_SECRET,
    code_verifier: codeVerifier, // PKCE
  }),
});

const { access_token, refresh_token, expires_in } = await response.json();
// Note: refresh_token is optional — not all servers issue one.
// For Google, you need to pass access_type=offline to receive a refresh_token.

授權伺服器會回傳:

  • access_token — 代表使用者呼叫 API 的憑證
  • refresh_token — 當 access token 過期時可換新(不需使用者重新登入)。不一定會回傳,取決於伺服器與請求 scope。
  • expires_in — access token 幾秒後過期

Step 5: 使用 Access Token 呼叫 Resource Server


const userInfo = await fetch('https://www.googleapis.com/calendar/v3/users/me/calendarList', {
  headers: {
    Authorization: `Bearer ${access_token}`,
  },
});

const calendars = await userInfo.json();
// { kind: 'calendar#calendarList', items: [...] }

Resource server 會驗證 token 並回傳受保護資料。當 access token 過期時,你可用 refresh token 靜默取得新 token,而不用再次提示使用者登入。

OAuth 2.0 Grant Types

上面的 Authorization Code flow 只是 OAuth 2.0 多種 grant type 之一。每種都對應特定場景:

Grant Type 使用情境 狀態
Authorization Code + PKCE Web、行動 App、SPA——任何面向使用者的應用程式 ✅ 推薦
Client Credentials Machine-to-machine(M2M)——不涉及使用者 ✅ 推薦
Device Code 智慧電視、CLI 工具——沒有瀏覽器的裝置 ✅ 推薦
Implicit 舊式 SPA——token 直接在 redirect 回傳 ❌ 避免使用——已被 Auth Code + PKCE 取代
Resource Owner Password App 直接收集帳號密碼 ❌ 避免使用——已被 Auth Code + PKCE 取代

若想更深入了解各 grant type 的差異與使用時機,可參考這篇:OAuth 2.0 grant types

OAuth 2.0 vs OpenID Connect (OIDC)

這是最常見的混淆點之一。短版如下:

  • OAuth 2.0 處理的是 授權——「這個 App 可以存取什麼?」
  • OpenID Connect (OIDC) 處理的是 驗證——「這個使用者是誰?」

OIDC 建立在 OAuth 2.0 之上。它在標準 OAuth 流程中加入 id_token(含使用者身分資訊的 JWT)、/userinfo endpoint,以及標準化的 openid scope。

實務上:當你在 OAuth 2.0 請求加入 scope=openid,就是在用 OIDC。若只請求 scope=read:email(沒有 openid),則是純 OAuth 2.0。

OAuth 2.0 OpenID Connect
目的 授權(權限委派) 驗證(身分確認)
回傳 token Access token Access token + ID token
使用者資訊 未標準化 標準化的 /userinfo endpoint
適用情境 把 API 存取權授予另一個 App 讓使用者可以「登入」你的 App

現代實作通常兩者一起用。若想看與 SAML 的更深入比較,可參考 OIDC vs SAML。你也可以使用 OIDC Discovery Endpoint Explorer 檢查任一 OIDC 供應者設定。

OAuth 2.0 vs JWT

OAuth 2.0 與 JWT 經常一起出現,但它們是不同層次的概念:

  • OAuth 2.0 是一個 協定——定義授權流程如何運作
  • JWT (JSON Web Token) 是一種 token 格式——定義如何把 claim 編碼成精簡、可簽章字串

JWT 常常 被用作 OAuth 2.0 的 access token 或 ID token,但 OAuth 2.0 並不強制 JWT。OAuth 2.0 的 access token 也可以是 opaque random string——resource server 再向 authorization server 驗證即可。

如果你的 OAuth 2.0 access token 是 JWT,你可以本地解碼驗簽,不必額外網路呼叫。若是 opaque token,通常需要呼叫 authorization server 的 introspection endpoint 才能驗證。

Scopes:控制授予哪些權限

Scope 會精準定義 client 能做什麼。它是授權請求裡的空白分隔字串:


scope=openid email profile calendar.readonly

使用者會在同意畫面看到這些 scope 並選擇是否同意。簽發出的 access token 也會受這些 scope 限制——即使 resource server 本來可能允許更高權限。

好的 scope 設計符合最小權限原則:只要求真正需要的權限。例如請求 calendar.readonly 而不是 calendar,可讓使用者清楚知道你不會修改行事曆。

PKCE:Public Client 必備

若你的 client 是行動 App、單頁應用(SPA),或任何無法安全保存 client secret 的應用,必須使用 PKCE(Proof Key for Code Exchange)。Public client 無法安全保存 secret,因為程式碼會下發到使用者裝置——任何人都可能檢視 App bundle 或瀏覽器 JS 抽出硬編碼 secret。

PKCE 透過下列機制防止授權碼攔截攻擊:client 先產生隨機 code_verifier,再雜湊成 code_challenge 並隨授權請求送出。之後用授權碼換 token 時,client 再送出原始 verifier,證明它就是啟動該流程的同一方。

可參考完整教學:PKCE 在 OAuth 2.0 中如何運作

常見 OAuth 2.0 錯誤與避免方式

  • 未驗證 state 參數 — 一定要比對是否與你送出的值一致,以防 CSRF 攻擊
  • 把 access token 存在 localStorage — 建議用 httpOnly cookie 或 server-side session;localStorage 可被 JavaScript 存取,容易受 XSS 影響
  • 在 SPA 使用 Implicit grant — 請改用 Authorization Code + PKCE;Implicit 已被淘汰有其原因
  • 未做 refresh token rotation — rotation 代表每次使用 refresh token 都會簽發新 token 並使舊 token 失效。若 token 被竊用,下一次你 App 合法使用時就能偵測異常並撤銷 session。
  • 請求過度寬泛的 scope — 只請求必要權限;越精準的權限越容易取得使用者同意

不必承擔 OAuth 2.0 的實作複雜度

從零實作 OAuth 2.0,代表你要自己處理 token 儲存、refresh 邏輯、PKCE、state 驗證、scope 管理與各種安全邊界情境。對多數團隊來說,使用現成驗證平台通常更實際。

Authgear 提供完整符合 OAuth 2.0 與 OIDC 的授權伺服器,包含預建登入 UI、token 管理、refresh rotation,以及開箱即用的社群登入供應者(Google、Apple、Facebook)。你可以不用自建整套基礎設施,就取得可上線的 OAuth 2.0 實作。

總結

關於 OAuth 2.0 如何運作,你只要記住以下重點:

  • OAuth 2.0 是授權委派——使用者可授權 App 代表自己操作,而不需分享密碼
  • 在 2026 年,幾乎所有面向使用者的 App 都應採用 Authorization Code + PKCE
  • Access token 短時效;refresh token 讓你可無感更新
  • OAuth 2.0 負責授權;若也需要驗證身分,加入 OIDC(scope=openid
  • JWT 是常與 OAuth 2.0 搭配的 token 格式,不是它的替代品