HTTP認証メソッドにContent-Type指定機能を追加

rails/rails

この変更により、HTTP認証の401レスポンスにContent-Typeを指定できるようになりました。これにより、JSONレスポンスを返すAPIなど、アプリケーションの要件に応じた認証エラーレスポンスの形式を統一できます。

背景

HTTP認証の401レスポンスは、従来はContent-Typeを制御する手段がありませんでした。authenticate_or_request_with_http_basic などのメソッドでカスタムメッセージは指定できましたが、レスポンスのContent-Typeは固定されていました。特にJSONベースのAPIでは、認証エラーもJSON形式で返したいという要件がありましたが、この実現には独自の実装が必要でした。

また、http_basic_authenticate_with クラスメソッドでは、既に内部的に存在していた message パラメータが公開されていませんでした。エラーメッセージをカスタマイズするには、より低レベルのメソッドを直接使用する必要がありました。

技術的な変更

HTTP認証の各メソッドに content_type パラメータが追加され、メソッドチェーン全体で伝播されるようになりました。

http_basic_authenticate_withの拡張

変更前:

def http_basic_authenticate_with(name:, password:, realm: nil, **options)
  raise ArgumentError, "Expected name: to be a String, got #{name.class}" unless name.is_a?(String)
  raise ArgumentError, "Expected password: to be a String, got #{password.class}" unless password.is_a?(String)
  before_action(options) { http_basic_authenticate_or_request_with name: name, password: password, realm: realm }
end

変更後:

def http_basic_authenticate_with(name:, password:, realm: nil, message: nil, content_type: nil, **options)
  raise ArgumentError, "Expected name: to be a String, got #{name.class}" unless name.is_a?(String)
  raise ArgumentError, "Expected password: to be a String, got #{password.class}" unless password.is_a?(String)
  before_action(options) { http_basic_authenticate_or_request_with name: name, password: password, realm: realm, message: message, content_type: content_type }
end

この変更により、クラスレベルの http_basic_authenticate_withmessagecontent_type の両方を指定できるようになりました。

メソッドチェーン全体への伝播

content_type パラメータは以下のメソッドチェーンを通じて最終的な認証要求メソッドまで伝播されます:

  • http_basic_authenticate_or_request_with
  • authenticate_or_request_with_http_basic
  • request_http_basic_authentication
  • HttpAuthentication::Basic.authentication_request

各メソッドのシグネチャが統一的に拡張されています:

def authenticate_or_request_with_http_basic(realm = nil, message = nil, content_type = nil, &login_procedure)
  authenticate_with_http_basic(&login_procedure) || request_http_basic_authentication(realm || "Application", message, content_type)
end

def request_http_basic_authentication(realm = "Application", message = nil, content_type = nil)
  HttpAuthentication::Basic.authentication_request(self, realm, message, content_type)
end

使用例

JSON形式の認証エラーレスポンスを返す場合の設定:

http_basic_authenticate_with(
  name: "admin", password: "secret",
  message: '{"error":"Access denied"}',
  content_type: "application/json"
)

messagecontent_type のどちらも省略可能で、既存の動作は変更されません。

設計判断

オプショナルパラメータとしての追加 が採用されました。

この変更では、既存のメソッドシグネチャに対して後方互換性を保つため、content_type をオプショナルパラメータとして追加しています。デフォルト値は nil で、指定されない場合は従来の動作が維持されます。Digest認証とToken認証のメソッドにも同様のパターンで content_type が追加されており、HTTP認証全体で一貫したインターフェースになっています。

また、既に存在していた message パラメータを http_basic_authenticate_with レベルに公開することで、低レベルメソッドを直接呼び出すことなくカスタマイズが可能になりました。テストコードでは content_type: "application/json" を指定した場合に、レスポンスの media_type が正しく設定されることが検証されています。

まとめ

本PRは、HTTP認証の401レスポンスにContent-Type制御機能を追加し、既存の message パラメータを公開した変更です。メソッドチェーン全体に統一的にパラメータを伝播させることで、Basic、Digest、Token認証すべてで一貫したカスタマイズが可能になり、特にJSONベースのAPIにおける認証エラーレスポンスの形式統一を実現しています。

記事メタデータ

Generated by:
Claude Sonnet 4.5 for DiffDaily

この記事はAIによって自動生成されています。内容の正確性については、必ずソースコードやPRを確認してください。

品質レビュー結果

Review Status:
リトライ後承認
Review Count:
3回 (改善を経て承認)
Reviewed by:
Gemini 2.5 Pro for DiffDaily

Review Criteria:

記事構成 ✓ PASS

Title, Context, Technical Detailの存在と明確さ

「リード文(総論)→背景・技術詳細・設計判断(各論)→まとめ(結論)」という構成が明確で、ガイドラインを完全に満たしています。

カスタムMarkdown構文 ✓ PASS

シンタックスハイライト・GitHubリンク記法の正確性

ファイル名付きのシンタックスハイライト(```言語:ファイルパス)が正しく使用されています。本文中に他のカスタム構文はありませんが、使用されているものは全て適切です。

対象読者への適合性 ✓ PASS

エンジニア向けの適切な技術レベルと表現

RailsのHTTP認証に関する深い内容であり、専門知識を持つエンジニアを対象読者として適切に記述されています。

パラグラフ・ライティング ✓ PASS

トピックセンテンス・1段落1トピック・段落長

各セクションが総論から始まり、各パラグラフもトピックセンテンスで開始されているため、非常に読みやすい構成です。1段落1トピックの原則も守られています。

Diff内容との照合 ✓ PASS

コードブロックとDiff内容の一致

記事内のすべてのコードブロックは、提供されたDiff情報(actionpack/lib/action_controller/metal/http_authentication.rb および actionpack/CHANGELOG.md)と完全に一致しており、正確に引用されています。

技術用語の正確性 ✓ PASS

技術用語の正確な使用

「メソッドチェーン」「オプショナルパラメータ」「後方互換性」などの技術用語が、文脈に沿って正確に使用されています。

説明の技術的正確性 ✓ PASS

技術的主張の正確性と論理性

「content_type パラメータがメソッドチェーン全体で伝播される」という説明は、Diffで示された複数のメソッドシグネチャの変更によって裏付けられており、技術的に正確です。

事実の突合 ✓ PASS

PR情報による主張の裏付け(ハルシネーション検出)

記事内のすべての主張(Content-Typeの追加、messageパラメータの公開、Digest/Token認証への適用)は、PRのTitle、Description、Diff内容によって完全に裏付けられています。ハルシネーションは検出されませんでした。

数値・固有名詞の確認 ✓ PASS

PR番号・コミットID・バージョン等の正確性

記事の末尾に記載されているPR番号(#56887)は、提供されたPR情報と一致しています。

タイトル・説明との一致 ✓ PASS

記事タイトル・説明とPR内容の一致

記事のタイトル「HTTP認証メソッドにContent-Type指定機能を追加」は、PRのタイトル「Add `content_type` parameter to `http_authentication` methods」の内容を的確に要約しています。

外部知識の正確性 ✓ PASS

PRに記載のない外部知識(LTS、サポート状況など)の不使用

記事には、バージョン情報やリリース予定など、PR情報に基づかない外部知識の記述は見られませんでした。

時間表現の正確性 ✓ PASS

時間表現がPR情報と一致しているか

「従来は...でした」といった表現は、PR Descriptionの「currently there's no way」という現状を正確に反映しており、時間表現の歪曲はありません。