今天,我們要來介紹OAuth2.0,在開場的時候,我們一定要先讓大家了解為什麼要用OAuth,以及相關的內容與知識。
學習一個新知識之前,我們肯定要先來背單字。這些都是關於OAuth的重要的關鍵字,大家可以先看一下,了解這些關鍵字的涵義。為什麼要先帶大家了解這些呢,因為這些詞就把OAuth的關鍵都說出來了,在這裡OAuth把東西分成角色、資源、驗證碼、伺服器這四個角色,讓權限可以在這些角色之間流動,所以了解這些,大致上我們也可以了解整個OAuth的流程了。
那麼就讓我們來先背個單字吧!
名詞 | 角色/含義 | 你腦中可以怎麼想 |
---|---|---|
Resource Owner | 資源擁有者(使用者) | 真正的主人:你 |
Client | 想代你做事的應用程式 | 例如你的 SaaS、手機 App、前端 SPA |
Resource Server | 放資料的 API 伺服器 | Google Drive API / GitHub API |
Authorization Server (AS) | 發 Token 的授權伺服器 | Google OAuth、GitHub OAuth、你公司的 IdP |
Access Token | 存取用「票」 | 拿它呼叫 Resource Server |
Refresh Token | 續票用「長期票」 | 換新 Access Token(本系列 Day 13 已解說) |
Scope | 權限範圍 | 只允許「讀取信箱」而不是「刪信」 |
Redirect URI | 授權後跳回的位置 | 必須完整比對,防止跳轉攻擊 |
State | CSRF 防護用亂數 | 授權前送、授權後驗(一定要) |
PKCE | Code 驗證強化(SHA256) | 手機/SPA 必備(避免授權碼被攔截) |
實務上預設優先選「Authorization Code + PKCE」。其餘流程比較像是特例,不是首選。
授權流程 | 適用場景 | 客戶端類型 | 使用者互動 | 是否用 PKCE | 優點 | 風險/限制 |
---|---|---|---|---|---|---|
Authorization Code + PKCE(首選) | Web SPA、Mobile App、Public Clients | Public/Confidential | 需要 | 是 | 安全、支援使用者同意、細粒度 scope | 需要正確設定 redirect/state |
Client Credentials | 服務對服務(機器到機器) | Server to Server | 否 | 否 | 簡單、無使用者互動 | 沒有使用者情境,代表機器身分 |
Device Authorization(裝置碼) | 電視、IoT、無鍵盤裝置 | Public | 需要(在另一裝置上) | 建議 | 使用者體驗可行 | 需實作人機交握流程 |
Refresh Token | 續票機制 | — | 否 | — | 提升體驗、縮短 Access 壽命 | 需旋轉/撤銷策略(Day 13/14) |
ROPC(密碼型)不建議 | 舊系統、專用 App | Public | 是(直接輸入密碼) | 否 | 看似簡單 | 高風險、破壞「不交出密碼」原則 |
Implicit 已淘汰 | 早期前端 | Public | 需要 | — | 少一步交換 | 易漏 Token,不要再用 |
剛剛說了Authorization Code(含 PKCE)是目前的首選,那就一定要先來介紹一下!
場景:你的前端或手機 App 要存取使用者在某服務的資料
流程步驟:
/authorize
):帶上 client_id / redirect_uri / scope / state / code_challenge
code
(以及你原本的 state
)code + code_verifier
→ 拿到 access_token
(與可選的 refresh_token
)access_token
去打 Resource Server APIPKCE:code_challenge = BASE64URL(SHA256(code_verifier));換票時要附上 code_verifier,避免授權碼在網路上被攔截後被他人使用。
流程圖
Client ── (1) /authorize?client_id&scope&state&code_challenge ──▶ Authorization Server
Client ◀───────────────────────── (2) user consent ───────────── Authorization Server
Client ◀─────────────── (3) redirect_uri?code&state ─────────── Authorization Server
Client ── (4) /token { code, code_verifier } ───────────────────▶ Authorization Server
Client ◀────────────── (5) access_token (+ refresh_token) ────── Authorization Server
Client ── (6) Authorization: Bearer <access_token> ────────────▶ Resource Server
在這裡,要注意的是Token分成很多種,有分成Access Token、 Refresh token、 ID Token這三種,這三種分別代表了不同的功能,我整理成一個列表給大家,要注意的是ID Token 不是拿去打呼叫API 的,那只是宣告身份使用,要打 API 就要用 Access Token。在這個OAuth中有一個OIDC,那就是ID Token, 是用來補上「我是誰」的標準化宣告。
類型 | 由誰消費 | 主要用途 | 有效期 |
---|---|---|---|
Access Token | Resource Server | 存取 API | 短 |
Refresh Token | Authorization Server | 換新 Access | 長 |
ID Token(OpenID Connect) | Client | 身分宣告(誰登入) | 短 |
每個新方法都有強化安全性的地方,但也有需要注意的地方。俗話說道高一尺,魔高一丈,就算使用了最先進的防護措施,如果漏了一些重要的步驟,那仍然是很容易被別人攻破的,所以以下列出10條在OAuth中要注意的安全要點給大家參考。
我們現在學到了OAuth2.0,那接下來我們可以拿來跟之前的JWT來比較一下,看一下兩個觀念的差異與關聯。因為我們使用的是Java Spring boot Security,我們可以再來看一下用Spring boot生態會可以怎麼使用。
在OAuth 2.0 中,是當你要「整合外部身分/資源」時才會使用的的標準授權協議。
在 Spring 生態中,我們的服務可以調整身份,充當成 Resource Server → 驗 Access Token(JWT/JWK、或 introspection),或者是可以部署/對接 Authorization Server(如 Keycloak、Auth0、Cognito、Spring Authorization Server)。
OAuth其實是JWT的一種延伸,將權限分成剛剛背的四大類項目,然後建立關聯的機制,中間也使用之前學過的Refrsh token、Access token來強化互動與防護,如此一來,使用者可以只用一個帳號,細分更多的使用權限給對應的APPs,相較起來更實用更簡單。
我自己現在遇到大部分新的APPs時也都使用OAuth的方法,操作起來很簡單好用。
那我們關於OAuth的教學就到這裡了,雖然非常冗長又有很多要背的知識,但只要知道這個觀念,後面的操作就會學得非常快了。感謝大家看到這裡,那我們就明天見囉!