OAuth 2.0 是一種授權(Authorization)框架,不是用來驗證身份的(不是 Authentication),而是允許第三方應用程式代表用戶訪問資源,但不暴露用戶密碼。
你去銀行(資源伺服器)開戶,銀行要你提供身份證(Access Token),但不是你的鑰匙(密碼),這個身份證是政府(身份提供者)發給你的。
OIDC 是建立在 OAuth 2.0 之上的一個身份驗證(Authentication)層。
- OAuth 2.0 ➜ 確認你有「權限」使用某些資源
- OIDC ➜ 確認你是「誰」
- ID Token(用 JWT 格式):包含用戶的資訊(例如名稱、email)
- Access Token:給應用程式使用,用來存取 API
SSO 是一種讓你只需登入一次,就能訪問多個應用的機制。
你登入 Google 帳號後,不需要重新登入 Gmail、YouTube、Google Drive,這就是 SSO。
🔧 SSO 通常就是靠 OAuth 2.0 + OIDC + JWT 完成的
- 各系統(A、B)共用同一個身份提供者(如 Auth0, Google, Okta)
- 登入一次後,身份提供者回傳 Token
- 各應用以此 Token 進行驗證與登入
- 如果 A、B 都使用同一個 Identity Provider:
- Access Token 通常不同,因為每個應用的
audience
不一樣 - ID Token 可以一樣,如果是針對相同使用者簽發
- Access Token 通常不同,因為每個應用的
- 通常身份提供者已回傳 JWT Token(ID Token、Access Token)
- 若服務端需要控制細節(如權限細分),可以自行產生內部用 Token(如 Session Token)
JWT 是一種 Token 格式,裡面可以裝使用者的資料,用於識別與授權。
Header.Payload.Signature
- Header:類型、加密算法
- Payload:資料(如 userId, email)
- Signature:加密簽名,防止偽造
JWT 是自包含的(self-contained),可以不用查資料庫就知道用戶資訊。
Token 是一段字串,用於代表某位使用者的權限與身份。
- Access Token:讓使用者去存取 API
- Refresh Token:讓使用者取得新的 Access Token
- ID Token:用於身份驗證(只有 OIDC 有)
Session 是伺服器上儲存使用者登入狀態的一種方式。
- 使用者登入成功後,伺服器建立一個 Session
- 伺服器產生一個
SessionID
- 這個
SessionID
會存到使用者的 Cookie 裡
下次請求時會帶上 Cookie,伺服器用這個 ID 去找登入資訊。
Cookie 是瀏覽器用來儲存資訊的小檔案,通常用來:
- 儲存 Session ID
- 儲存用戶偏好設定
- 追蹤用戶行為(Analytics)
攻擊方式:駭客將惡意 JavaScript 注入頁面,竊取 Cookie 或操作使用者的行為。
HttpOnly
:設定 Cookie 為 HttpOnly,瀏覽器無法透過 JavaScript 存取 Cookie。Content-Security-Policy
:限制哪些腳本可以執行,防止注入攻擊。Input Sanitization
:所有輸入內容都要嚴格驗證與過濾。
攻擊方式:使用者登入 A 網站後,駭客在 B 網站中夾帶惡意請求,冒充使用者發送操作。
SameSite
Cookie 屬性:Strict
:完全禁止跨站請求帶上 Cookie(最安全)Lax
:允許某些安全的 GET 請求None
:允許跨站請求,但必須搭配Secure
- CSRF Token:每次請求都必須帶上一組難以偽造的隨機字串,用來驗證請求來源。
- 驗證 Referer / Origin Header:檢查請求來源是否合法。
在實務上,有些系統會將 JWT 存在 Cookie 中以實現 SSR 的身份驗證與自動帶入。
HttpOnly
: 阻止 JavaScript 取得 Token,避免 XSSSecure
: 只允許 HTTPS 傳輸,防止中間人攻擊SameSite
: 設定為Lax
或Strict
以防止 CSRF
- 容易被 JavaScript 存取,暴露在 XSS 風險下
- 後端驗證 JWT 的有效性與過期時間
- 可選擇在 Server 端加強驗證機制,例如 JWT Blacklist 機制
- 用戶點選「使用 Google 登入」
- 被導向到 Google 的 OIDC 認證頁(OAuth 2.0 流程)
- 用戶登入後,Google 回傳:
- Access Token(存取權限)
- ID Token(身份資訊,JWT)
- 應用程式解析 ID Token,確認用戶身份
- 前端儲存 Token 或 Server 建立 Session,將 SessionID 寫入 Cookie
答案是:✅ 可以!
但前提是你必須使用正確的授權流程與參數設定。
要在 OpenID Connect(OIDC)中取得 Refresh Token,必須滿足以下幾點:
- 最安全、最常見的流程。
- 支援取得 Access Token、ID Token、Refresh Token。
- 請求中需包含 scope:
scope=openid offline_access
openid
是 OIDC 必要 scope。offline_access
是請求 Refresh Token 的關鍵!
GET https://auth.example.com/authorize?
response_type=code&
client_id=abc123&
redirect_uri=https://your.app/callback&
scope=openid offline_access profile email
POST /token
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&
code=xyz456&
redirect_uri=https://your.app/callback&
client_id=abc123&
client_secret=super-secret
{
"access_token": "abc...",
"id_token": "eyJ...",
"refresh_token": "xyz...",
"expires_in": 3600,
"token_type": "Bearer"
}
- 並不是所有 OIDC 提供者預設會發
refresh_token
,需查看服務設定(如 Google、Auth0、Keycloak 等)。 - 若使用隱式流程(Implicit Flow),不會提供 Refresh Token。
- 若在前端單頁應用(SPA)中使用,建議搭配 PKCE 流程與安全存儲方式。
- 某些瀏覽器(例如 Safari)對第三方 Cookie 的限制可能會影響 Token 管理。
若你正在使用特定 OIDC 提供者(如 Cognito、Auth0、Google OAuth),建議查閱其官方文件,確認:
- 是否需要額外設定
offline_access
- 是否預設支援 Refresh Token
若需要範例程式碼(如前端或後端實作),可以再說,我可以補上具體範例 🙌