HTTPQUERY
日本語

Authorization

使い方

Authorization リクエストヘッダーは保護されたリソースへのアクセスを得るためのもので、通常はアクセスが制限されていることをクライアントが知らされた後に送信されます。例えば、WWW-Authenticate ヘッダーを含む 401 Unauthorized の HTTP レスポンスをサーバーから受け取った後、クライアントはこの形で認証情報を提出します。

注意

リクエストが別のオリジンへリダイレクトされると、ブラウザは Authorization ヘッダーを取り除きます。これにより、リダイレクト先がサードパーティのサーバーを指している場合の認証情報の漏えいを防ぎます。この挙動は WHATWG Fetch Standard で定義されており、現代のすべてのブラウザでサポートされています。クロスオリジンのリダイレクトをまたいで Authorization ヘッダーに依存するアプリケーションは、最終的な遷移先で再認証を扱う必要があります。curl、Python Requests、Go の HTTP クライアントといったツールも同じ慣習に従います。

authentication-scheme

authentication-scheme は必須のディレクティブで、任意の方式固有のパラメーターを伴います。方式は認証情報のエンコード方法を定義します。一般的な手法には Basic、Bearer、Digest、Negotiate があります。

例

この例では、クライアントが basic の認証方式を使っています。必須のパラメーターとして、認証情報は username:password の組を base64 でエンコードしたものです。

Authorization: Basic RXhhbXBsZTphaQ==

Bearer トークンは OAuth 2.0 の API でよく使われます。トークンは不透明な文字列か、認可サーバーが発行した署名付きの JWT です。

Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...

トラブルシューティング

認証の失敗は、想定外の 401 レスポンスや、黙って破棄される認証情報として現れることがよくあります。

クロスオリジンのリダイレクトで認証情報が取り除かれる。ブラウザや HTTP クライアントは、リクエストが別のオリジンへリダイレクトされると Authorization ヘッダーを削除します。対処法は、最終的な遷移先へ直接認証情報を送るか、リダイレクト完了後に再認証することです。curl -L -v でリダイレクトの連鎖を調べ、どこでヘッダーが消えるかを確認してください。

Basic 認証における Base64 エンコードの誤り。エンコードされた文字列には、ユーザー名とパスワードを区切るコロンがちょうど 1 つ含まれていなければなりません。コロンの欠落や二重エンコードされた値は、サーバーが拒否する壊れたトークンを生みます。echo -n “user:pass” | base64 で生の値を確認し、リクエストで送られたヘッダーの値と比較してください。

Bearer トークンの期限切れまたは不正な形式。トークンは有効期限のクレームを持ち、サーバーは期限切れのトークンを 401 で拒否します。jwt.io または echo "" | base64 -d で JWT をデコードし、exp フィールドを確認してください。トークンの更新ロジックは、サーバーがリクエストを拒否した後ではなく、トークンが期限切れになる前に実行されなければなりません。

サーバーが WWW-Authenticate を省略することによる 401 のループ。サーバーが 401 を返すものの WWW-Authenticate ヘッダーを含めないため、クライアントは期待される方式を知る手がかりがありません。curl -I https://example.re/resource でレスポンスヘッダーを確認し、サーバーの設定にこのヘッダーが含まれていることを確かめてください。nginx では auth_basic ディレクティブが自動的にヘッダーを追加します。独自のバックエンドでは明示的にヘッダーを設定する必要があります。

CORS プリフライトが Authorization ヘッダーをブロックする。Authorization を伴うクロスオリジンのリクエストは、プリフライトの OPTIONS リクエストを引き起こします。サーバーはプリフライトに対して Access-Control-Allow-Headers: Authorization を返さなければなりません。値が欠けていたり誤っていたりすると、ブラウザは認証情報を送る前にリクエストをブロックします。DevTools の Network タブには、プリフライトが別の OPTIONS のエントリとして表示されます。

curl が誤ったエンドポイントへ認証情報を送る。curl -H “Authorization: Bearer …” を -L と併せて実行するとリダイレクトをたどりますが、クロスオリジンのホップではヘッダーが取り除かれます。-L を使わずに curl -v を実行して正確なエンドポイントへヘッダーを送るか、—location-trusted を渡してリダイレクトをまたいだ認証情報の転送を強制してください(信頼できるドメインに限って慎重に使ってください)。

Basic 対比 Bearer

Basic と Bearer は最も一般的な 2 つの認証方式であり、それぞれ異なる用途に向いています。

Basic は、username:password の組を Base64 でエンコードしたものをリクエストのたびに送ります。このエンコードは簡単に元へ戻せるため、HTTPS が必須です。認証情報は静的でユーザーアカウントに紐づいているため、パスワードが漏えいした場合はパスワード自体の変更が必要になります。Basic は、トークン管理が不要な複雑さをもたらすような社内ツールや単純な連携に向いています。

Bearer は、認可サーバーが発行する不透明なトークン(多くの場合 JWT)を使います。トークンには有効期限があり、スコープ付きの権限を持ち、元のパスワードを変更せずに失効させられます。Bearer は API や OAuth 2.0 のフローにおける標準的な仕組みです。盗まれたトークンは寿命もスコープも限られているため、漏えいしたパスワードに比べて被害範囲が小さくなります。

どちらの方式も、ヘッダーの値の中で認証情報を平文のまま送信します。方式自体に暗号化の機能はありません。選ぶ方式に関わらず HTTPS が必要です。

Fetch API で Bearer トークンを使うクロスオリジンの API リクエストです。

fetch('https://api.example.re/data', {
  headers: {
    'Authorization': 'Bearer eyJhbGci...'
  }
})