iT邦幫忙

2026 iThome 鐵人賽

DAY 3
0
Software Development

從登入到授權-現代軟體的身分架構指南系列 第 3

Day 03|HTTP 驗證機制:Basic Auth、Digest Auth、API Key 與 Session

  • 分享至 

  • xImage
  •  

前言

上一篇我們先把 MFA、OTP、TOTP 與 WebAuthn / Passkey 講完,重點放在「使用者要怎麼證明自己是本人」。

但登入驗證成功之後,系統還有另一個問題要處理:HTTP 本身是無狀態(stateless)的協定。也就是說,伺服器不會天生記得上一個請求是誰送來的。

如果每次操作都要重新輸入密碼、重新跑一次 MFA,使用者體驗一定會很差。所以今天要來看幾種常見的 HTTP 驗證機制:它們分別用什麼方式,讓每一次 Request 都能帶著某種「身份憑證」。

今天內容涵蓋:

  1. HTTP 驗證機制可以分成哪兩大陣營
  2. Basic Auth:最單純的帳密驗證
  3. Digest Auth:密碼不落地的加強版
  4. API Key:應用程式的通行證
  5. Session-based 登入:伺服器幫你記住
  6. Session 跟 Cookie 差在哪

一、認識常見的 HTTP 驗證機制:兩大陣營

工程師平常寫程式、呼叫 API 時,會遇到一個很基礎的問題:一支 API 要怎麼知道「誰在呼叫我」?

常見做法其實可以先分成兩大陣營:

陣營 包含的方式 共同特色
傳統 HTTP 驗證方式 Basic Auth、Digest Auth、API Key、Session 驗證資訊(帳密、識別碼、或伺服器端記錄的編號)本身就是「憑證」,每次請求附上就好
Token-Based Auth Bearer & JWT Token、Access & Refresh Token 先驗證一次,換到一份可獨立驗證真偽的「憑證」,之後靠這份憑證代表身份

今天先把傳統 HTTP 驗證方式這一陣營拆開來看。Token-Based Auth 底下的 Bearer、JWT Token、Access Token、Refresh Token,內容比較多,留到下一篇一次講清楚。


二、Basic Auth:最單純的帳密驗證

工程師要呼叫公司一支很舊的內部維運工具 API,這支工具沒有登入頁面、也沒有 Session,最基礎的驗證方式就是 Basic Auth

https://ithelp.ithome.com.tw/upload/images/20260909/20181928CBjKTmwO0c.png

做法很直接:把「帳號:密碼」用冒號接起來,整串用 Base64 編碼,放進請求的 Authorization header 送出去。

流程如下:

  1. 客戶端第一次沒帶認證資訊,直接請求資源。
  2. 伺服器回應 401 Unauthorized,並在 WWW-Authenticate: Basic realm="..." 裡告知需要用 Basic Auth。
  3. 客戶端把 帳號:密碼 做 Base64 編碼,放進 Authorization: Basic <編碼結果> 重新發送請求。
  4. 伺服器解碼、比對帳密,通過就放行。

例如帳號 gloria、密碼 mysecret,送出的 header 會長這樣:

Authorization: Basic Z2xvcmlhOm15c2VjcmV0

風險:Base64 只是編碼,不是加密,任何人攔截到封包都能直接還原出帳密明文。所以 Basic Auth 一定要搭配 HTTPS 使用,而且 HTTP 本身沒有「登出」的概念,只能靠瀏覽器自己清掉快取的帳密。


三、Digest Auth:密碼不落地的加強版

如果不想讓密碼(哪怕只是編碼過的)直接出現在封包裡,可以改用 Digest Auth。它用的是「challenge-response」的方式,全程只傳送密碼算出來的雜湊值,密碼本身從頭到尾不會上網路。

https://ithelp.ithome.com.tw/upload/images/20260909/20181928AgLZfhnYXF.png

流程如下:

  1. 客戶端請求資源。
  2. 伺服器回應 401,並在 WWW-Authenticate: Digest 裡附上 realm、一次性亂數 nonce 等參數。
  3. 客戶端用密碼、nonce 等資訊算出一段摘要,放進 Authorization: Digest 裡重新送出。
  4. 伺服器用同樣的方式算一次摘要,跟收到的比對,一致就算驗證成功。

摘要用的雜湊演算法可以用 algorithm 參數指定:舊版本默認是 MD5,但現行標準 RFC 7616 已新增支援 SHA-256、SHA-512-256,並明確標示 MD5 「NOT RECOMMENDED」,實作時改用 SHA-256 會更安全。

因為 nonce 每次都不一樣,就算封包被攔截,攻擊者也無法直接拿去重放使用。不過因為實作複雜,Digest Auth 在一般 Web 應用已經很少見,比較常出現在網路電話(SIP)之類的場景。


四、API Key:應用程式的通行證

工程師的團隊要串接一個地圖服務(例如 Google Maps),這類服務通常不需要知道「是哪個使用者」,只需要知道「是哪個應用程式/專案在呼叫」,這時候用的就是 API Key

https://ithelp.ithome.com.tw/upload/images/20260909/201819289gcjW076Lo.png

API Key 是服務提供者發給你的一串識別碼,可以放在三個地方:

  • Header:例如 Authorization: Bearer <api_key>(這裡的 Bearer 是驗證方案名稱,細節下一篇再展開),或自訂欄位 X-API-Key: <api_key>
  • URL 查詢參數:例如 ?api_key=<api_key>
  • 請求本文:放進 JSON 的欄位裡

跟 Basic Auth 的差別:Basic Auth 驗證的通常是「這個人是誰」,API Key 驗證的通常是「這個應用程式/專案是誰」,很適合 server-to-server、公開資料 API、地圖服務這類場景,也常被拿來做流量控管與計費依據。

風險:API Key 通常長期有效,而且本身沒有內建的過期機制,除非自己額外實作,否則一旦外洩,任何拿到這把 Key 的人都能以你的名義持續存取資源,很難追查是誰在用,所以多半只用來存取公開或非機密的資料;真的牽涉到機密資料,就得換成更嚴謹的使用者驗證方式。

跟 JWT 的本質差異:API Key 只是一串隨機字串,本身不帶任何資訊,伺服器想知道這把 Key 屬於誰、有什麼權限,都得去查資料庫;而下一篇會提到的 JWT,則是把身份資訊直接編碼進 Token 裡,伺服器不需要查資料庫就能驗證。


五、Session-based 登入:伺服器幫你記住

使用者帳號通過密碼與 MFA 之後,系統知道「這確實是本人」。但 HTTP 本身是無狀態(stateless)的協定——伺服器不會自動記得上一個請求是誰送來的。如果每次操作都要重新輸入密碼、重新跑一次 MFA,會非常麻煩,使用者體驗也會不佳。

https://ithelp.ithome.com.tw/upload/images/20260909/20181928Qo6XNpnMVK.png

Session-based 登入的做法是:登入成功後,伺服器在自己這邊建立一筆記錄,叫做 Session,裡面記著「這是哪個帳號、什麼時候登入的、登入到什麼時候過期」。伺服器接著把這筆記錄的編號(Session ID)交給瀏覽器,通常存在一個 Cookie 裡。

之後使用者每發出一次請求,瀏覽器都會自動帶上這個 Cookie。伺服器拿到 Session ID,就去自己的資料庫或記憶體裡查:「這個編號對應的是哪個 Session?還沒過期嗎?」查得到而且沒過期,就當作這個人還是登入狀態。

可以把這個機制想成寄物櫃:你進門的時候把外套交給服務生(登入),服務生把外套掛好,只給你一張號碼牌(Session ID)。你身上什麼資訊都不用帶,只要拿著號碼牌,服務生看到號碼就知道要拿哪件外套給你。

Session-based 登入的特性:

  • 使用者身上的資料很單純,只有一個 ID,實際內容都放在伺服器那邊,這種設計叫做有狀態(stateful)
  • 因為記錄都在伺服器手上,要強制某個人登出,只要把伺服器上那筆 Session 刪掉就好,效果立即生效。
  • 缺點是伺服器要負責保管所有人的 Session,一旦後端變成好幾台機器,就得想辦法讓每一台機器都查得到同一份 Session 資料。

風險:Session Fixation(session 固定攻擊)

OWASP 目前的 Session Management 安全指南中,仍將這種攻擊列為重點風險之一:攻擊者先想辦法讓受害者的瀏覽器帶著一組「攻擊者自己事先指定好」的 Session ID(例如透過惡意連結或埋在連結裡的參數),受害者用這組 ID 登入成功後,伺服器就把這組 ID 跟受害者的身份綁在一起,攻擊者接著直接拿同一組 ID 就能冒充受害者,根本不需要偷密碼。

目前業界公認的標準做法是:使用者登入成功後,伺服器要重新產生一組全新的 Session ID,而不是沿用登入前就已經存在的舊 ID。常見後端框架如 PHP 的 session_regenerate_id()、Laravel 的 session()->regenerate(),都有內建方法可以直接呼叫。


六、Session 跟 Cookie 差在哪?

很多人會把兩者混為一談,其實它們扮演的角色完全不同:

比較項目 Session Cookie
存放位置 伺服器端 使用者的瀏覽器
本質 伺服器保存的一筆登入紀錄(資料) 瀏覽器的儲存機制,什麼資料都能放
裡面裝的是什麼 使用者身份、登入時間、過期時間等實際資料 在 Session-based 登入裡,通常只放 Session ID 這組指標
誰能讓它失效 伺服器隨時可以刪除,效果立即生效 由瀏覽器依 Expires/Max-Age 管理,伺服器刪不到使用者本機的 Cookie

簡單說:Session 是伺服器手上那份記錄,Cookie 只是把「找到這份記錄的鑰匙(Session ID)」放在使用者瀏覽器裡的其中一種容器——Cookie 本身不是 Session,也不一定要拿來裝 Session ID。

這種「伺服器記住你」的做法,跟下一篇要介紹的 Token-Based Auth「你自己帶著身份走」剛好是兩種相反的思路,兩者的完整比較也留到下一篇。


小結

概念 說明
Basic Auth 帳密 Base64 編碼直接附在請求上,簡單但沒有加密
Digest Auth 用 challenge-response 傳送密碼算出的摘要,避免密碼明文出現在網路上
API Key 代表應用程式身份的識別碼,常用在 server-to-server、公開 API 或計費控管
Session-based 登入 伺服器記住登入狀態,使用者只帶著一組 Session ID
Cookie 瀏覽器端的儲存機制,在 Session-based 登入裡常用來保存 Session ID

今天把傳統 HTTP 驗證方式(Basic Auth、Digest Auth、API Key、Session-based)講完了,但故事還沒結束——Token-Based Auth 底下其實藏著 Bearer、JWT Token、Access Token、Refresh Token 好幾個要分開釐清的概念,還有它跟 Session-based 之間的完整比較,這些就留到下一篇一次講清楚。


參考資源


上一篇
Day 02|MFA、OTP 與 Passkey:為什麼密碼不夠安全?
系列文
從登入到授權-現代軟體的身分架構指南3
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言