使用方法
- 輸入使用者名稱和密碼。
- 把生成的 Authorization 請求頭複製到你的客戶端中,或者用 curl 命令測試請求。
- 如需檢視現有請求頭,把它貼上到解碼區域,即可顯示使用者名稱和密碼。
HTTP Basic 認證的工作原理
Basic 認證由 RFC 7617 定義。訪問受保護的資源時,伺服器返回 401 Unauthorized 和 WWW-Authenticate: Basic realm="..." 響應頭。客戶端隨後用冒號連線使用者名稱和密碼,將結果進行 Base64 編碼,並在每個請求中傳送:
Authorization: Basic base64(username ":" password)
# RFC 7617 中的範例:使用者 "Aladdin",密碼 "open sesame"
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
瀏覽器會自動完成這一過程並彈出登入對話方塊;指令碼和 API 客戶端則通常在第一個請求中就直接帶上該請求頭,而不必等待伺服器質詢。由於冒號用來分隔兩個值,使用者名稱中不能包含冒號,密碼中則可以。伺服器可以在質詢中加上 charset="UTF-8",表示非 ASCII 字元的憑據應使用 UTF-8 編碼。
Base64 不是加密
請求頭看起來像亂碼,但任何看到它的人都能在幾秒內還原出密碼,用本頁的解碼功能或任何 Base64 解碼 工具都可以。因此 Basic 認證只能在 HTTPS 下使用,由 TLS 在傳輸過程中加密請求頭。另外還要注意:
- 憑據會隨每個請求傳送,只要有一次請求走了明文 HTTP,就會洩露;
- 代理、負載均衡器和除錯工具可能會記錄
Authorization請求頭,除非專門配置不記錄; - 瀏覽器會一直記住輸入過的憑據,直到關閉瀏覽器,而且沒有標準的退出登入方式。
對於公開 API,可撤銷的 API 權杖或 OAuth 更合適。Basic 認證仍然適用於內部工具、測試環境網站,以及通過 TLS 進行的伺服器間呼叫。
在程式碼中傳送請求頭
# curl 會自動生成請求頭
curl -u 'user:password' https://api.example.com/
// JavaScript fetch(btoa 只能處理 Latin-1 字元)
fetch(url, { headers: { Authorization: 'Basic ' + btoa('user:password') } })
# Python requests
requests.get(url, auth=('user', 'password'))
不要把憑據直接寫在 URL 中,例如 https://user:password@host/。RFC 3986 已棄用這種寫法,它會留在瀏覽器歷史和伺服器日誌裡,現代瀏覽器也對其加以限制。
常見問題
如何解碼 Basic 認證請求頭?
把請求頭貼上到解碼區域,使用者名稱和密碼會立即顯示出來。任何 Base64 解碼工具都能得到同樣的結果,這也正是該請求頭只能通過 HTTPS 傳輸的原因。
密碼中可以包含冒號嗎?
可以。伺服器會在解碼後的第一個冒號處分割,之後的所有內容都屬於密碼。但使用者名稱中不能包含冒號。
HTTP Basic 認證安全嗎?
在 HTTPS 下配合強密碼且不重複使用,傳輸過程中的憑據是受保護的。但憑據會隨每個請求傳送,也不能像權杖那樣自動過期。切勿在明文 HTTP 下使用。
為什麼密碼含有中文或帶重音的字元時登入失敗?
charset="UTF-8";如果沒有宣告,一些較舊的伺服器可能按 ISO-8859-1 處理,比較的就是不同的位元組。我的密碼會被髮送到別處嗎?
不會。請求頭由瀏覽器中的 JavaScript 生成,不會傳輸任何資料。不過,與他人分享生成的 curl 命令時,最好使用測試賬號。