你第一次打開一個網站,註冊頁面上可能同時放著「使用 Google 繼續」、「使用 Apple 登入」、「使用 GitHub 登入」或「使用 Microsoft 帳號」。按下其中一個按鈕之後,畫面跳到原本的平台,請你登入、確認權限,再把你帶回來。幾秒鐘後,新網站就知道你是誰,甚至可能可以讀取你的基本資料、Email,或在你同意的情況下存取其他資源。
這個流程看起來像「把 A 平台帳號借給 B 網站登入」,但背後最重要的設計其實是:你不需要把 A 平台的密碼交給 B 網站。OAuth 2.0 讓第三方應用可以在你同意之後取得有限範圍的存取權;如果目的是登入與確認身分,實務上通常還會搭配 OpenID Connect,也就是 OIDC。
先把兩句話分開:
OAuth 2.0 主要解決「這個 App 可以代表我做什麼?」
OpenID Connect 主要補上「這個登入者是誰?」
OAuth 原本不是為了「登入」而設計的
OAuth 的全名裡有 Authorization,重點是授權。假設你使用一個排程工具,希望它可以讀取你的某個服務資料。最糟的做法,是直接把那個服務的帳號密碼交給排程工具,讓它假裝成你登入。這等於把整把鑰匙交出去:它能看到什麼、能做什麼,很難精確限制;你想取消權限時,甚至可能只能改密碼。
OAuth 2.0 改成另一種模型。第三方 App 不拿你的密碼,而是把你帶到真正掌管帳號與資源的平台。你在那裡完成登入與授權,平台再給第三方 App 一張「通行證」——通常就是 access token。這張通行證可以限制範圍、設定有效期限,也可以被撤銷。
你在授權平台確認權限
授權平台 → code / token → 第三方 App
因此 OAuth 的核心不是「把帳號送過去」,而是把一部分權限委派出去。
Scope:不是「同意登入」就等於全部開放
OAuth 常見一個重要概念叫 scope。它描述這次授權要求哪些範圍。某個 App 可能只需要知道你的基本帳號資訊;另一個 App 可能需要讀取檔案;再另一個 App 可能需要替你建立行事曆事件。這些權限不應該被混成一個「同意」按鈕背後的無限存取。
所以當授權畫面列出「查看你的基本資料」、「讀取某類資料」或其他權限時,你真正要看的不是那顆漂亮的登入按鈕,而是它正在要求哪些 scope。同樣都是「使用 GitHub 登入」或「連結 Google 帳號」,不同 App 要的權限可能完全不同。
最常見的 Authorization Code Flow 在走什麼?
現代 Web 與 App 很常使用 authorization code flow。流程裡最容易誤會的地方,是平台通常不會直接在第一次跳轉時把長期可用的 access token 塞進網址。它會先回一個短暫的 authorization code,讓 client 再去 token endpoint 交換真正的 token。
2. 你登入並確認授權
3. 平台把你導回預先登記的 redirect URI,附上 authorization code
4. App 用 code 向 token endpoint 換取 token
5. App 使用 access token 呼叫受保護的 API
這裡的 redirect URI 不是隨便填一個「登入完回哪裡」。它是安全邊界的一部分。授權平台需要知道 code 應該送回哪個已登記的位置;目前 OAuth 2.0 的安全最佳實務也強調 redirect URI 應嚴格比對,避免授權結果被送到攻擊者控制的地方。
PKCE:就算 code 被截走,也不能直接拿去換 token
Authorization code 本身如果被攔截,還是可能有風險,所以現代 OAuth 流程常搭配 PKCE,全名是 Proof Key for Code Exchange。client 在流程開始前先產生一個只有自己知道的隨機值,再把它衍生出的 challenge 放進授權請求。之後拿 authorization code 去換 token 時,client 必須證明自己持有原本的那個值。
可以把它想成:authorization code 不是一張撿到就能用的兌換券,它還要配上另一半證明。OAuth 的現行安全最佳實務已經把 authorization code 搭配 PKCE 放在非常核心的位置,尤其是瀏覽器與原生 App 這類無法安全保存固定 client secret 的環境。
Access Token 不是你的密碼,也通常不是「身分證」
Access token 的工作,是讓 client 存取被授權的資源。例如某個 App 拿到一枚具有特定 scope 的 token,之後就可以拿它呼叫對應 API。resource server 看到 token 後,判斷這枚憑證能不能做這件事。
這也是為什麼 access token 很敏感。雖然它不是你的原平台密碼,但如果是常見的 bearer token,誰拿到有效 token,誰就可能在 token 權限範圍內使用它。因此前端網址、log、錯誤訊息或公開 repo 都不是適合亂放 token 的地方。
Refresh Token 是拿來換新的 Access Token
Access token 通常不會設計成永遠有效。當它過期後,如果每次都要求使用者重新走完整授權流程,體驗會很差。因此某些 OAuth 流程還會提供 refresh token。client 可以在符合規則的情況下,用 refresh token 向 authorization server 取得新的 access token。
但 refresh token 通常比短效 access token 更需要保護,因為它能持續換出新的存取權。不同平台會有不同的發放、輪替、失效與撤銷規則,不能看到「OAuth」就假設所有 provider 的 token 生命周期完全一樣。
那「登入」到底是怎麼來的?這就是 OIDC
如果 OAuth 主要是授權,就會出現一個問題:第三方 App 拿到 access token,並不代表它應該把這枚 token 當成「這個人是某某某」的可靠身分證明。這正是 OpenID Connect 要補上的部分。
OIDC 建在 OAuth 2.0 之上,增加了一套身分層。最重要的東西之一是 ID token。它通常是 JWT,裡面包含由 identity provider 簽發的 claims,讓 client 能驗證這次登入事件以及使用者身分相關資訊。像 Google 的 Sign in with Google 與 Microsoft identity platform 都有正式的 OIDC 流程。
OIDC ID token →「這次登入的是誰?」
所以平常大家口語上說「OAuth 登入」並不奇怪,但如果要講技術邊界,最好知道:OAuth 2.0 與 OIDC 解決的是相鄰但不同的問題。
Google、Apple、GitHub、Microsoft,看起來一樣,底下不一定一樣
使用者看到的介面很像:按一顆按鈕、跳轉、確認、回來。但不同平台支援的協定、endpoint、scope、token 格式、使用者資料欄位與安全要求並不完全相同。Google 與 Microsoft 都提供標準 OIDC 能力;Apple 提供 Sign in with Apple 的認證流程;GitHub 則有 OAuth Apps,讓使用者授權第三方 App 存取 GitHub 帳號相關資源。
也就是說,前端可以把按鈕排得很整齊,但後端不能把所有 provider 當成「換一個 logo 就結束」。真正整合時,仍要看各平台的官方文件、redirect URI 規則、client 註冊方式、scope、token endpoint 與回傳資料。
第三方網站到底拿不到什麼?
如果流程正確,第三方網站通常不需要也不應該知道你在原平台的密碼。你的密碼是在 Google、Apple、Microsoft、GitHub 或其他身分提供者自己的登入頁面處理;第三方收到的是授權結果、code、token 或經驗證的身分資訊。
但這不代表「第三方登入 = 沒有風險」。你仍然可能授權太大的 scope;token 可能被不安全地保存;client 本身可能是惡意的;redirect URI、state、PKCE 或 token 驗證也可能實作錯誤。OAuth 把「直接交出密碼」這個危險問題拆掉了,但安全性仍然取決於整條流程。
OAuth 不是權限系統的全部
最後還有一個很容易混淆的地方:OAuth 可以告訴某個服務「這個 client 被授權以某些 scope 存取資源」,但你的產品內部仍然需要自己的 authorization 規則。就算使用者透過 Microsoft 或 Google 成功登入,也不代表他自動是你系統的 admin;就算 access token 有效,也不代表所有資料都應該對他開放。
第三方登入解決的是「怎麼安全地把身分與授權結果帶進來」;你自己的後端仍然要決定「這個人在我的系統裡能做什麼」。
把整段流程濃縮成一句話
你按下 Google、Apple、GitHub、Microsoft 或其他平台的登入按鈕時,真正發生的通常不是「把帳號密碼送給新網站」。比較接近的是:原平台先確認你,再按照你同意的範圍,把一份有限、可驗證、可撤銷的授權結果交給第三方;如果還需要確認身分,OIDC 再提供標準化的 identity layer。
知道這個差異之後,再看到 client_id、redirect_uri、scope、authorization code、access token、refresh token、ID token 或 PKCE,就不會覺得它們只是登入頁後面突然冒出的一堆名詞。每一個東西都在回答一個很具體的問題:誰在要求、要去哪裡、要哪些權限、授權結果交給誰,以及這次登入到底能不能被相信。
OAuth 最值得記住的,不是某一組 endpoint,而是一個設計原則:不要為了讓另一個 App 幫你做一件事,就把整個帳號的鑰匙交出去。
資料來源
本文的 OAuth 2.0 定義與角色依據 RFC 6749;現代安全建議參考 RFC 9700;OIDC 定義依據 OpenID Connect Core 1.0。平台例子另參考 Google、Microsoft、Apple 與 GitHub 官方開發者文件。