HTTP認証スキームをケースインセンシティブにマッチさせる
Token と Bearer の認証スキームが、HTTP Authorization ヘッダーの auth‑scheme 部分を大文字小文字を区別せずに判定するようになり、RFC 9110 に準拠した動作になります。
背景
現在の実装では Token と Bearer の認証スキームがケースセンシティブに比較されていたため、bearer abc123 のように小文字で送られたヘッダーはトークンが取得できず、認証が失敗して 401 応答が返されました。 Token モジュールの TOKEN_REGEX と ActionDispatch::Request#bearer_token が大文字のみを許容していたことが根本原因です。これにより、実運用で広く見られる小文字表記が正しく処理されませんでした。
RFC 9110 §11.1 では auth‑scheme がケースインセンシティブであることが規定されています。実際のクライアントやプロキシは bearer や TOKEN といった非正規表記を送出することが多く、Rails の Basic 認証モジュールはすでにケースインセンシティブで比較していますが、Token と Bearer だけが例外となっていました。この不整合が認証失敗の原因となっていたため、統一的な挙動へ修正する必要がありました。
ケースセンシティブな比較は認証フロー全体で失敗の原因となっていたため、RFC の要件と他モジュールとの一貫性を保つべく、スキーム比較をケースインセンシティブに変更することが求められました。
技術的な変更
Token モジュールの TOKEN_REGEX にケースインセンシティブフラグ i が追加され、スキーム部分のマッチングが大小文字を無視して行われるようになりました。
変更前:
TOKEN_REGEX = /^(Token|Bearer)\s+/
変更後:
TOKEN_REGEX = /^(Token|Bearer)\s+/i
ActionDispatch::Request#bearer_token メソッドでも同様に正規表現に i フラグが付与され、Authorization ヘッダーからトークンを抽出する際にスキームの大小文字を無視できるようになりました。
変更前:
authorization.to_s[/\ABearer (.+)\z/, 1]
変更後:
authorization.to_s[/\ABearer (.+)\z/i, 1]
テストが追加され、bearer, BEARER, token, TOKEN といった様々な表記で認証が成功することが確認されました。actionpack/test/controller/http_token_authentication_test.rb ではスキームの大小文字を変化させたリクエストがすべて成功し、actionpack/test/dispatch/request_test.rb では bearer_token がケースインセンシティブに動作することを検証しています。
設計判断
ケースインセンシティブ化は既存の Basic モジュールと一貫性を持たせることを目的として実装されました。Basic がすでに正規表現に /i フラグを使用しているため、Token と Bearer にも同様のフラグを付与することで認証スキーム全体で統一された挙動を実現しています。
正規表現フラグの追加のみで実装されたため、Token と Bearer の呼び出しロジックやメソッドシグネチャは変更されず、既存コードへの影響は最小限に抑えられました。これにより後方互換性が保たれ、既存アプリケーションが改修なしで新しい挙動を利用できます。
この設計選択により、コードベースへのリスクを抑えつつ RFC 準拠という要件をシンプルに達成したと言えます。
まとめ
Token と Bearer の認証スキームがケースインセンシティブにマッチするようになり、HTTP 認証の RFC 準拠が実現されました。正規表現フラグの追加とテスト拡充だけで実装されたため、既存の動作を壊すことなく認証の堅牢性が向上しています。