セキュリティ / 認証

APIの主な認証方式まとめ(Bearer・APIキー・mTLS・JWT)

APIの認証って「トークン認証」くらいしか意識していなかったのですが、整理してみると色々あったのでまとめておきます。ついでに、よく混同される OAuth や JWT との関係もメモしておきます。

APIの主な認証方式

方式しくみ使われている例特徴
Basic認証毎回 ID:パスワード を Base64 にして送る社内ツール、古いAPI一番簡単。毎回パスワードを送るので HTTPS 必須
APIキー発行した固定のキーを毎回送るClaude API、Google Maps など多くの SaaS簡単で広く使われている。期限がないことが多く、漏れたら作り直し
トークン認証一度認証して期限付きトークンをもらい、以後はそれを送るOAuth 2.0 全般、自前のトークン発行秘密を送る回数が減る。期限を付けられる
リクエスト署名(HMAC)秘密鍵でリクエストの中身ごと署名する。秘密そのものは送らないAWS(Signature V4)、決済サービスの Webhook改ざんや使い回しを防げる。実装はやや大変
mTLS(クライアント証明書)通信開始時にお互いが証明書を見せ合う銀行・金融機関同士の API秘密の文字列を送らない。とても強いが証明書の管理が手間
セッションCookieログイン後、サーバーが覚えたセッションを Cookie で照合ブラウザで使う Web アプリ画面のある Web アプリ向け。システム間 API ではあまり使わない

IP制限は単独では「認証」とは言いませんが、どの方式とも組み合わせられる追加の守りになります。

強さのイメージ
◀ 弱い強い ▶
  • 1Basic認証毎回パスワードを送る
  • 2APIキー期限のない固定の秘密
  • 3トークン認証期限付きの秘密
  • 4リクエスト署名秘密を送らない
    改ざんも検知
  • 5mTLS証明書で
    お互いを確認

※実際の強さは、組み合わせと運用しだいです。

OAuth 2.0 と Bearer は別もの

「Bearer ヘッダーでトークンを送っている=OAuth 2.0」ではありません。決めている仕様が別です。

仕様決めていること
RFC 6749(OAuth 2.0 本体)トークンをどうやって発行するか。認可サーバー、grant_type、/token エンドポイントの形式など
RFC 6750(Bearer Token Usage)発行されたトークンをどうやって送るか。Authorization: Bearer の書き方

トークンの発行が独自方式なら「Bearer トークン認証」と呼ぶのが正確です。なお OAuth はもともと認可(何をしてよいか)の仕組みで、「ログインした人が誰か」を伝える部分は OpenID Connect が OAuth 2.0 の上に足したものです。

システム間の API なら、発行エンドポイントの入出力を以下の形に合わせるだけで「OAuth 2.0 Client Credentials Grant 準拠」と言えます。

POST /token
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials&client_id=xxx&client_secret=yyy

# 応答
{"access_token":"...","token_type":"Bearer","expires_in":1800}

ちなみに、ID/パスワードを直接送ってトークンをもらう「Resource Owner Password Credentials Grant」は、OAuth のセキュリティ指針(RFC 9700)で使ってはならないとされました。他社のアプリに本人のパスワードを渡すことになるのが理由で、人が使う場合は Authorization Code + PKCE が今の標準です。

トークンはどのヘッダーで送る?

標準は Authorization ヘッダーです(RFC 9110)。

Authorization: Bearer eyJhbGciOi...
Authorization: Basic dXNlcjpwYXNz

ただ HTTP はどんなヘッダー名を付けても自由なので、独自ヘッダーも規格違反ではありません。よく見るのは以下です。

  • x-api-key / X-API-Key(AWS API Gateway、Claude API など)
  • Ocp-Apim-Subscription-Key(Azure API Management)
  • Authorization: token xxx(GitHub の古い書き方。ヘッダーは標準でスキームが独自)
独自ヘッダーの弱点
  • ログで伏せてもらえない:多くのツールやプロキシは Authorization を秘密として自動でマスクするが、独自ヘッダーはそのまま記録されることがある
  • キャッシュ事故:共有キャッシュは Authorization 付きリクエストの応答を他人に使い回さない(RFC 9111)。独自ヘッダーだとこの保護が効かない
  • X- で始まる名前は非推奨(RFC 6648)。ただし今も広く残っている

一番避けたいのは URL にトークンを入れる方式(?token=xxx)です。アクセスログやブラウザ履歴、Referer に残ってしまいます。

トークンとパスワードの違い

似ていますが、観点別に比べると違いがみえてきます。

観点パスワードトークン
何を表すか「私は本人です」を証明するもの「本人確認が済んだ」という結果
誰が作るか人が決めて覚えるシステムが発行(長いランダム文字列や署名付きデータ)
使える範囲アカウントでできることすべて一部の権限に絞れる(スコープ)
取り消し変えると全端末に影響1つだけ無効にできる
送る回数ログインのときだけリクエストのたびに送る

毎回送る分だけ盗まれる機会も多いので、トークンには短い有効期限を付けて被害を小さくします。

JWT 認証って何?

JWT(JSON Web Token、RFC 7519)は認証方式ではなく、トークンの形式です。「JWT 認証」は「JWT 形式のトークンを使った Bearer トークン認証」の通称です。ヘッダー・ペイロード・署名を「.」でつないだ形をしています。

{ "alg": "RS256", "typ": "JWT" }          ← ヘッダー
{ "sub": "user01", "aud": "order-api",
  "exp": 1791960000, "scope": "read" }      ← ペイロード(クレーム)
                                           ← 署名
クレーム意味
sub誰のトークンか
exp有効期限(1970年からの秒数)
iat発行時刻
iss発行者
audどのAPI向けか
JWT の注意点
  • 署名だけの JWT(JWS)は中身を誰でも読める。秘密の情報は入れない(暗号化したいなら JWE)
  • 検証時はアルゴリズムを固定する(alg を none に書き換える攻撃がある)
  • 期限が来るまで途中で無効にできないので、有効期限は短くする

中身を見たいときは jwt.io が便利です。ただし本番のトークンは貼らないこと。

スポンサーリンク
タイトルとURLをコピーしました