跳至主要內容
Skip to content

身份驗證、授權與身份識別的差異

很多登入系統的混亂,都是從概念混在一起開始的:信箱驗證到底算不算登入?Google 登入是 OAuth 還是身份驗證?JWT 裡有 user id 是不是就代表有權限?401 和 403 到底差在哪?

一句話回答:身份識別 Identity Proofing 是確認「你是不是你宣稱的那個人」,身份驗證 Authentication 是確認「這次操作是不是本人登入」,授權 Authorization 是確認「登入後你能不能做這件事」;三者會串在同一個登入流程裡,但解決的是不同問題,系統設計時必須拆開。


一、 必考觀念

1. 三個概念解決三個問題

概念英文核心問題常見例子
身份識別Identity Proofing你是不是你宣稱的那個人信箱驗證、手機驗證、健保卡、自然人憑證
身份驗證Authentication這次登入是不是本人操作帳號密碼、Session、TOTP、Passkey
授權Authorization登入後你能做什麼RBAC、權限碼、API scope、資料權限

可以用一個句子記:

text
Identity Proofing:你是誰?
Authentication:你怎麼證明這次是你?
Authorization:你被允許做什麼?

這三件事在產品上常常連在一起,但工程上最好拆開,否則會把安全責任放錯地方。

2. 註冊、登入、權限是不同階段

以一個普通會員系統為例:

text
註冊
-> 驗證信箱
-> 登入
-> 取得 session / token
-> 進入會員中心
-> 檢查是否能查看訂單、修改資料、刪除帳號

每一步的安全意義不同:

流程對應概念說明
驗證信箱身份識別的一部分確認這個 email 可被使用者控制
輸入帳密身份驗證確認這次登入者知道正確憑證
建立 session身份驗證狀態後續請求不用每次輸入密碼
檢查能否刪除訂單授權確認使用者是否有該操作權限

信箱驗證不是登入;登入成功也不代表什麼都能做。

3. 身份系統要分清楚「證明強度」

不同方式的可信程度不同:

方式證明了什麼強度
信箱驗證使用者控制某個 email inbox低到中
手機 OTP使用者控制某個手機號碼
帳號密碼使用者知道某組秘密低到中,取決於密碼與防護
TOTP使用者持有設定過的驗證器中到高
Passkey / WebAuthn使用者持有私鑰與裝置驗證器
自然人憑證使用者持有憑證並知道 PIN
健保卡使用者持有特定身份載具高,依整合流程而定

系統設計時要問:

text
這個場景需要多高的身份信任?
失敗或冒用的代價是什麼?
使用者體驗能承受多少驗證摩擦?

不是所有產品都需要最高強度;但高風險場景不能只靠低強度驗證。


二、 Identity Proofing:身份識別

1. 身份識別是在建立信任

身份識別要回答:

這個帳號背後的人,是否真的控制某個身份憑證或聯絡方式?

常見例子:

  • 使用者點擊信箱驗證連結。
  • 使用者輸入手機簡訊 OTP。
  • 使用者插入自然人憑證並輸入 PIN。
  • 使用者用健保卡完成身份確認。
  • 使用者在銀行臨櫃完成 KYC。

這些流程不一定等於「登入」。它們是在提高系統對使用者身份的信任程度。

2. 信箱驗證不是完整身份驗證

信箱驗證通常只能說明:

text
這個使用者目前能控制這個 email。

它不能保證:

  • 使用者真實姓名。
  • 使用者年齡。
  • 使用者是否為某個自然人。
  • 使用者未來永遠控制這個信箱。

所以信箱驗證適合:

  • 確認通知管道。
  • 降低假帳號。
  • 啟用帳號。
  • 忘記密碼。

但不適合單獨用來證明高信任身份。

3. 身份識別可能需要分級

很多系統會有身份等級:

等級例子可以做什麼
未驗證只註冊帳密瀏覽、收藏
已驗證信箱點擊 email link發文、接收通知
已驗證手機完成 SMS OTP提高帳號恢復能力
已完成實名憑證、文件、KYC金融、醫療、政府服務

這就是為什麼「帳號存在」和「身份可信」不能畫上等號。


三、 Authentication:身份驗證

1. Authentication 是登入本人

身份驗證要回答:

這次請求是不是由該帳號本人發起?

常見方式:

  • 密碼。
  • 一次性驗證碼。
  • TOTP。
  • Passkey。
  • 憑證。
  • 已存在的 session。
  • 有效的 access token。

登入成功後,系統通常會建立某種登入狀態:

text
session id
access token
refresh token
device session

後續請求會帶上這些憑證,讓伺服器知道「目前請求來自已驗證的登入狀態」。

延伸讀:HTTP 專題:Session 與 Token 的抉擇

2. 認證因素分三類

常見 MFA 會把身份驗證因素分成三種:

因素意義例子
你知道的東西Knowledge密碼、PIN
你擁有的東西Possession手機、驗證器、硬體金鑰、憑證卡
你本身的特徵Inherence指紋、Face ID、虹膜

多因素驗證的重點是不同因素組合,而不是「輸入兩次密碼」。

例如:

text
密碼 + TOTP
密碼 + Passkey
自然人憑證 + PIN

這比單純帳號密碼更難被盜用。

3. 登入狀態不是使用者本人

這句很重要:

伺服器看到 session / token,只能知道這個請求帶著有效登入憑證,不等於百分之百知道本人坐在電腦前。

所以高風險操作常需要重新驗證:

  • 修改密碼。
  • 修改信箱。
  • 提款、轉帳。
  • 查看敏感個資。
  • 下載醫療資料。
  • 關閉 MFA。

這叫 step-up authentication,也就是在風險提高時要求更強的驗證。


四、 Authorization:授權

1. Authorization 是能不能做

授權要回答:

這個已登入使用者,是否被允許執行這個操作?

常見授權模型:

  • Role-based access control:角色權限。
  • Permission-based access control:權限碼。
  • Attribute-based access control:根據屬性判斷。
  • Scope-based access control:OAuth API scope。
  • Data-level permission:資料範圍權限。

例如:

text
user:list
user:create
user:delete
order:refund
medical-record:read

登入成功只代表 authentication 通過;是否能刪除使用者,要看 authorization。

延伸讀:Vue 專題:Vue 權限與路由守衛設計

2. 401 和 403 差異

這是面試常問。

狀態碼意義例子
401 Unauthorized尚未通過身份驗證,或登入狀態失效沒 token、session 過期
403 Forbidden已登入,但沒有權限不是 admin、缺少 permission

簡化記法:

text
401:你是誰,我還不知道或不再相信。
403:我知道你是誰,但你不能做這件事。

前端處理也不同:

  • 401:清登入狀態,導 login,保留 redirect。
  • 403:顯示無權限頁面或禁用操作,不一定登出。

3. 前端授權不是安全邊界

前端可以做:

  • 隱藏 menu。
  • 禁用 button。
  • 路由守衛。
  • 顯示 403 頁。
  • 根據權限調整 UI。

但真正授權必須在後端檢查:

text
每個敏感 API
每個資料範圍
每個高風險操作

因為使用者可以繞過前端,直接呼叫 API。


五、 OAuth、OIDC 與第三方登入的常見混淆

1. OAuth 2.0 主要是授權框架

OAuth 2.0 的核心問題不是「登入你是誰」,而是:

使用者如何授權某個應用存取另一個服務上的資源?

例如:

text
你授權某個工具讀取你的 Google Calendar。

這比較像授權,而不是純身份驗證。

延伸讀:HTTP 專題:OAuth 2.0 完整圖解

2. OpenID Connect 才補上身份層

OpenID Connect 是建立在 OAuth 2.0 上的身份層,常用於第三方登入。

它會引入:

  • id token。
  • user claims。
  • userinfo endpoint。
  • subject identifier。

所以比較精準的說法是:

text
OAuth 2.0:授權存取資源。
OpenID Connect:在 OAuth 2.0 之上提供登入身份資訊。

3. 第三方登入後仍要建立本地帳號

很多產品會讓使用者用 Google / LINE / GitHub 登入。

但系統內部通常仍要有自己的 user:

typescript
type User = {
  id: string
  email: string
  status: 'active' | 'disabled'
}

type ExternalIdentity = {
  provider: 'google' | 'line' | 'github'
  providerUserId: string
  userId: string
}

原因是:

  • 你的系統需要自己的權限模型。
  • 使用者可能綁定多種登入方式。
  • 第三方 email 可能變更或未驗證。
  • 第三方帳號停用不一定等於本地帳號刪除。

第三方登入只解決「如何證明外部身份」,不等於你的系統授權已經完成。


六、 常見流程拆解

1. 一般會員註冊

text
使用者輸入 email/password
-> server 建立 pending user
-> 寄出 verification email
-> 使用者點擊連結
-> user.emailVerified = true
-> 使用者登入
-> 建立 session

概念拆解:

步驟概念
建立帳號帳號資料建立
點擊驗證信身份識別的一部分
輸入密碼登入身份驗證
進入會員中心需要授權檢查

2. 管理員登入後刪除使用者

text
admin 輸入帳密
-> 通過 MFA
-> 建立 admin session
-> 進入使用者管理頁
-> 點擊刪除
-> server 檢查 user:delete permission
-> 寫入 audit log

概念拆解:

步驟概念
帳密 + MFA身份驗證
進入管理頁授權
刪除使用者授權 + 稽核
高風險操作再次驗證Step-up authentication

3. 政府或醫療服務登入

text
使用者選擇高信任登入方式
-> 使用健保卡、自然人憑證或行動身份工具
-> 系統確認身份
-> 建立服務內 session
-> 使用者查看或申辦服務
-> 高風險操作寫入稽核紀錄

這類場景的重點是:

  • 身份識別強度高。
  • 操作紀錄重要。
  • 可能需要重新驗證。
  • 權限和資料範圍要非常嚴格。

政府憑證與醫療身份整合細節會變,正式寫到健保卡、自然人憑證、TW FidO 時應以官方文件為準。


七、 追問題庫

Q1:Authentication 和 Authorization 差在哪?

Authentication 是確認你是誰,或這次登入是否可信;Authorization 是確認你能不能做某件事。

例如登入成功是 authentication,登入後能不能刪除使用者是 authorization。

Q2:信箱驗證算不算身份驗證?

信箱驗證更接近身份識別或聯絡方式驗證。它證明使用者能控制某個 email,但不等於每次登入都由本人操作,也不等於能做所有敏感操作。

Q3:401 和 403 怎麼分?

401 是未登入、token 過期或身份驗證失敗;403 是已登入但權限不足。

401 通常導 login,403 通常顯示無權限。

Q4:OAuth 是身份驗證嗎?

OAuth 2.0 本身主要是授權框架。第三方登入常用的是 OpenID Connect,它在 OAuth 2.0 之上提供身份層,例如 id token 和 user claims。

面試時不要把 OAuth 和 OIDC 完全混在一起。

Q5:有 JWT 就代表有權限嗎?

不一定。

JWT 可能只是登入狀態或身份聲明。真正能不能操作某個 API,仍要看 token 內容、scope、permission,以及後端授權檢查。

Q6:前端路由守衛可以保護系統安全嗎?

只能改善體驗,不能當安全邊界。

前端路由守衛可以避免使用者看到不該看的頁面入口,但 API 權限和資料權限一定要後端檢查。


八、 實作題

題目:設計一個會員系統的身份流程

需求:

  • 使用者可以註冊帳號。
  • 註冊後要驗證信箱。
  • 使用者可以登入。
  • 登入後才能查看個人資料。
  • 修改密碼前要重新驗證。
  • 管理員可以停用使用者。

可以這樣拆:

text
Identity Proofing
  -> email verification

Authentication
  -> password login
  -> session / token
  -> re-auth before password change

Authorization
  -> user can read own profile
  -> admin can disable users

Audit
  -> login success / failure
  -> password change
  -> admin disable user

資料模型可以先簡化:

typescript
type User = {
  id: string
  email: string
  emailVerified: boolean
  passwordHash: string
  status: 'pending' | 'active' | 'disabled'
}

type Session = {
  id: string
  userId: string
  createdAt: string
  expiresAt: string
  lastAuthenticatedAt: string
}

type Permission = 'profile:read:self' | 'user:disable'

API 判斷:

text
GET /me
  -> 需要 authentication
  -> 只能讀自己的資料

PATCH /me/password
  -> 需要 authentication
  -> 需要近期重新驗證

POST /admin/users/:id/disable
  -> 需要 authentication
  -> 需要 user:disable authorization
  -> 寫 audit log

這題的重點不是資料表多完整,而是能否把身份識別、身份驗證、授權、稽核拆清楚。


九、 資深視角

1. 身份信任是分層累積的

不要把所有使用者都看成同一種狀態。

例如:

text
未登入
已登入
已驗證 email
已啟用 MFA
已完成實名
近期完成重新驗證

不同功能可以要求不同信任等級:

功能要求
看公開內容不需登入
留言已登入或已驗證 email
修改密碼已登入 + 近期重新驗證
提款已登入 + MFA + 風險檢查
查看醫療資料高信任身份 + 稽核

這比單純 isLogin = true 更接近真實系統。

2. 身份驗證和授權都要可撤銷

成熟系統要能處理:

  • 使用者登出。
  • token 失效。
  • 密碼被重設。
  • 管理員停用帳號。
  • 權限被移除。
  • 第三方帳號解除綁定。
  • 裝置遺失。

如果系統發出去的憑證完全不能撤銷,就要很小心使用場景和過期時間。

3. 安全與體驗要一起設計

安全不是一直要求使用者驗證。

比較好的做法是:

  • 低風險操作保持順暢。
  • 高風險操作 step-up authentication。
  • 新裝置或異常地點提高驗證強度。
  • 使用者能管理登入裝置。
  • 重要操作有通知與稽核紀錄。

這樣才能在安全與可用性之間取得平衡。


總結

問題回答重點
Identity Proofing確認使用者身份或聯絡方式可信度
Authentication確認這次登入或請求是否可信
Authorization確認已登入使用者是否能做某件事
信箱驗證驗證聯絡方式,不等於完整登入
OAuth / OIDCOAuth 偏授權,OIDC 提供身份層
401 / 403401 是未通過身份驗證,403 是已登入但無權限
前端權限只能改善體驗,後端才是安全邊界

一句完整的面試回答可以是:

身份識別、身份驗證和授權要分開看。Identity Proofing 是確認使用者是不是他宣稱的人,例如信箱驗證、手機驗證、自然人憑證;Authentication 是確認這次登入是否可信,例如帳號密碼、Session、TOTP、Passkey;Authorization 是確認已登入使用者能不能做某件事,例如 RBAC、permission、scope 和資料權限。信箱驗證不等於登入,登入成功也不代表有所有權限。401 代表未通過身份驗證或登入狀態失效,403 代表已登入但權限不足。前端可以用路由守衛和按鈕權限改善體驗,但真正的 API 授權和資料權限一定要在後端檢查。

延伸閱讀