Authorization ヘッダー - Basic / Bearer / API Key

初級 | 14分 で読める | 2026.05.02

APIが「誰からのリクエストか」を確かめるとき、よく使われるのが Authorization ヘッダーです。

値には認証方式を示す scheme と、その方式で使う credentials を入れます。

Authorization: <scheme> <credentials>

この記事では、クライアントがヘッダーを送り、サーバーが検証してレスポンスを返す1回の往復を中心に、BasicとBearerを比べます。

認証方式・検証・401/403を含む総合仕様は本記事で扱い、SPAが直接送る構成とBFF経由の構成を選ぶ判断はSPA・BFFでAuthorizationヘッダーをどう使い分けるかで比較します。

クライアントがHTTPSでAuthorizationヘッダーを送り、サーバーが認証情報の検証と操作権限の確認を別々に行う図

先に結論

Authorizationヘッダーの流れは次の4段階です。

  1. クライアントがAPI仕様に合うschemeを選ぶ
  2. credentialsを付けてリクエストする
  3. サーバーがcredentialsの正当性と有効性を検証する
  4. 認証後、対象resourceを操作できるか認可する

代表例は次の2つです。

Authorization: Basic YWxpY2U6c2VjcmV0
Authorization: Bearer eyJhbGciOi...

BasicBearer がscheme、その後ろがcredentialsです。

認証と認可を分ける

似た言葉ですが、役割は異なります。

  • 認証(authentication): 誰なのかを確かめる
  • 認可(authorization): その人が操作してよいかを確かめる

有効なトークンを持っているだけで、すべてのデータへアクセスできるわけではありません。

たとえば、ログイン済みの生徒が自分の提出物を読めても、別の生徒の提出物を読めるとは限りません。サーバーは認証後に、resourceの所有者やroleも確認します。

Basic認証

Basicでは、一般に ユーザー名:パスワード をBase64で表現します。

たとえば次の文字列を使います。

alice:secret

Base64にすると次の値です。

YWxpY2U6c2VjcmV0

リクエストは次のようになります。

GET /api/profile HTTP/1.1
Host: example.com
Authorization: Basic YWxpY2U6c2VjcmV0

サーバーは概ね次を確認します。

  1. Authorization があるか
  2. schemeが Basic
  3. credentialsをBase64デコードできるか
  4. 最初のコロンでユーザー名とパスワードを分けられるか
  5. 保存済み情報と安全な方法で照合できるか
  6. 利用者が対象resourceへアクセスできるか

Base64は暗号化ではない

Base64はバイナリを文字列として表す符号化です。誰でも元へ戻せます。

printf 'YWxpY2U6c2VjcmV0' | base64 --decode

結果:

alice:secret

したがってBasic認証は必ずHTTPS上で使います。HTTPで送れば、通信を観察できる相手に認証情報を知られる危険があります。

さらに、毎回パスワード相当の値を送る性質があります。用途を限定し、現在の一般ユーザー向けWebログインではセッションやトークン方式も検討します。

Basicをcurlで試す

curlは -u でBasic認証ヘッダーを作れます。

curl -i \
  -u 'alice:secret' \
  https://example.com/api/profile

実際に作られる値を確認するには、次のようにBase64へ変換できます。

printf 'alice:secret' | base64

出力:

YWxpY2U6c2VjcmV0

シェル履歴やプロセス一覧に秘密情報が残る可能性があります。本物のパスワードをコマンドへ直接書く運用は避け、検証用の値だけで試してください。

Bearer認証

Bearerでは、発行済みのアクセストークンを送ります。

GET /api/profile HTTP/1.1
Host: example.com
Authorization: Bearer eyJhbGciOi...

Bearerは「その値を持っている人が使える」という性質を表します。盗まれたトークンを第三者が送っても、サーバーから見れば正規の所持者と区別できない場合があります。

そのため、次が重要です。

  • HTTPSだけで送る
  • ログへトークン全体を出さない
  • URLのquery stringへ入れない
  • 必要最小限の権限と有効期限にする
  • 漏えい時に無効化または失効できるようにする

Bearerトークンは必ずJWTではない

BearerはAuthorization schemeの名前です。credentialsの形式をJWTに限定しません。

サーバー内部でだけ意味が分かるランダム文字列もBearerトークンとして使えます。JWTかどうかは、そのAPIや認証基盤の仕様を確認します。

Bearerをサーバーが検証する

サーバーはschemeを確認し、トークンを認証基盤の仕様に従って検証します。

JWTなら、一般に専用ライブラリを使って次を確認します。

  • 署名が正しいか
  • 許可したalgorithmか
  • issuer(発行者)が正しいか
  • audience(利用先)が正しいか
  • expiration(有効期限)が切れていないか

署名を確認せずpayloadを読むだけでは認証になりません。また、payloadの値を確認できても、その利用者が対象resourceを操作できるかは別に認可します。

不透明なランダムトークンなら、データベースや認証サーバーへ照会し、有効期限・失効状態・scopeなどを確認します。

自作の文字列解析だけで済ませず、利用する認証サービスやフレームワークの公式ライブラリに従います。

Bearerをcurlで送る

curl -i \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
  https://example.com/api/profile

YOUR_ACCESS_TOKEN は説明用のplaceholderです。実際のトークンを共有チャット、ソースコード、スクリーンショットへ貼らないでください。

環境変数を使う場合も、端末の履歴やCIログへ表示されないよう扱います。

fetchで送る

ブラウザのJavaScriptからBearerトークンを送る例です。

const response = await fetch("https://api.example.com/profile", {
  headers: {
    Authorization: `Bearer ${accessToken}`,
  },
});

別originのAPIなら、サーバー側のCORS設定で Authorization ヘッダーを許可する必要があります。

ブラウザへ渡したトークンは、ページ上で動くJavaScriptから触れられる可能性があります。保存場所を安易に決めず、XSS対策、トークンの寿命、更新方法を認証基盤の推奨構成に合わせます。

サーバー専用のAPIキーや長期secretをフロントエンドへ埋め込んではいけません。配信されたJavaScriptは利用者から見えます。

401 Unauthorized

認証情報がない、壊れている、期限切れなどで認証できない場合は、通常 401 Unauthorized を返します。

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer realm="api"
Content-Type: application/json

{"error":"invalid_token"}

WWW-Authenticate は、どの認証schemeで資格情報を提示すべきかを示すchallengeです。

Basicなら次のような形です。

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Basic realm="members"

名前はUnauthorizedですが、実務では「まだ認証できていない」と覚えると区別しやすくなります。

403 Forbidden

認証はできたが、その操作を許可されていない場合は通常 403 Forbidden を返します。

HTTP/1.1 403 Forbidden
Content-Type: application/json

{"error":"insufficient_permission"}

例:

  • 一般利用者が管理者APIを呼んだ
  • 別の利用者が所有するresourceを編集しようとした
  • 必要なscopeを持たないトークンで操作した

つまり、基本の区別は次の通りです。

状態ステータス
認証情報がない、または無効401
認証済みだが権限不足403

存在自体を隠したいresourceでは、情報露出を避けるため別の応答設計を選ぶこともあります。API全体で方針を統一します。

API Keyは送付方法がAPI次第

API keyはサービスが発行する識別・認証用の秘密値です。ただし、API Key という標準Authorization schemeが一律に決まっているわけではありません。

API仕様によって Authorization: Bearer YOUR_API_KEYX-API-Key: YOUR_API_KEY などの形式があります。必ず公式ドキュメントに従います。

query stringへAPI keyを入れる方式は、アクセスログや履歴、参照元情報に残りやすいため、選べるならヘッダーを使います。

API keyもソースコードへ直書きせず、サーバー側の環境変数やsecret管理機能で扱います。ブラウザへ配信するコードへ入れた値は秘密にできません。

よくある間違い

  • schemeを書かずトークンだけ送る: Bearerを要求するAPIなら Authorization: Bearer <token> とします。
  • BasicのBase64を暗号化だと思う: すぐ復号できるためHTTPSが前提です。
  • JWTなら検証せず信用する: 署名、issuer、audience、期限などを検証します。
  • 401と403を同じ意味で使う: 認証できなければ401、認証後の権限不足なら403が基本です。
  • 有効なトークンなら全resourceを許可する: 所有者、role、scopeなども確認します。

DevToolsで確認する

NetworkタブでRequest Headersのscheme、Status、401応答の WWW-Authenticate を確認できます。画面共有時はAuthorizationの値を隠してください。

まとめ

Authorization: <scheme> <credentials> という形で送り、往復で見ると処理は明確です。

クライアントがcredentialsを送る
→ サーバーが認証する
→ 対象resourceへの権限を確認する
→ 成功、401、403のいずれかを返す

覚える要点は次の通りです。

  • Basicはユーザー名とパスワード相当をBase64で表すが、暗号化ではない
  • Bearerは所持者が使えるため、漏えいさせない
  • Bearerトークンは必ずしもJWTではない
  • 401は認証できない状態、403は認証後の権限不足
  • API keyの送付場所はAPI仕様に従う
  • 認証と認可はサーバーで別々に確認する

次に読む

参考リソース

← 一覧に戻る
PR
PR
PR
PR