HTTP Basic Authenticationは、リソースをパスワードで保護する最も古くて単純な方法だ。ブラウザがユーザー名とパスワードを尋ね、それらは毎回のリクエストとともにサーバーへ送られる。この単純さこそが最大の弱点でもある。
Authorizationヘッダーの作られ方
ユーザー名とパスワードをコロンで連結し(username:password)、その文字列全体をBase64エンコードしてAuthorization: Basic <エンコード済み文字列>ヘッダーに入れる。最初の認証に成功した後は、ブラウザがこのヘッダーを以降すべてのリクエストに自動的に付け続ける。
Base64は「暗号化」ではない
Base64は暗号化ではなくエンコード方式にすぎない。鍵など一切なしで、誰でも数秒でusername:passwordの形に復元できる。保護されていない公衆Wi-Fiなどでリクエストを傍受されれば、認証情報は即座に漏洩する。
日本語の認証情報とBase64のサイズ
Base64は文字ではなくバイト列をエンコードするため、元の文字列のエンコーディングが結果を左右する。半角英数字はUTF-8で1バイトだが、ひらがな・カタカナ・漢字はいずれも3バイトを占める。たとえばパスワード123のような日本語入りのパスワードは、同じ文字数の英数字パスワードよりBase64トークンが明らかに長くなる。Basic Auth自体は元々ASCII文字のユーザー名・パスワードを想定して設計されており、非ASCII文字の扱いは長らく標準化されていなかった——2015年のRFC 7617で、ようやく任意のcharset="UTF-8"パラメータが正式に追加され、クライアントとサーバーの解釈のずれを避けられるようになった。
何に使うか
- 開発中のstagingサーバーや社内ツールを、手早くパスワードで保護する。
- curlやPostmanでAPIを手動テストするための正しいAuthorizationヘッダーを作る。
- 平文のHTTP上でBasic Authを使うことが、なぜ深刻なセキュリティ上の問題とされるのかを理解する。
Basic Authに標準のログアウトはない
ブラウザは認証情報をキャッシュし、タブを閉じるまで同じoriginへの以降のリクエストすべてにAuthorizationヘッダーを自動付与し続ける——プロトコル自体に標準の「ログアウト」ボタンは存在しない。ユーザーを強制的にログアウトさせるため、サーバー側はわざと別のrealm値で401を返す、あるいはユーザー自身がブラウザのタブを全部閉じることに頼るといった、やや強引な工夫をすることになる。