JWT と OAuth の違い:主な違い、連携方法、およびベストプラクティス
JWT と OAuth の違い、それぞれがどう補完し合うか、両者を効果的に使うためのベストプラクティスを簡単に解説します。
もし認証に初めて触れる場合や、ログイン・支払い・ユーザーデータを扱うアプリを構築しているなら、「JWT」と「OAuth」という言葉を目にしたことがあるでしょう。一見すると複雑で「バックエンド専用」のトピックのように思われがちですが、実はセキュリティエンジニアだけのものではありません。
API、サードパーティ連携、AI・MCP・エージェントベースの新しい技術の登場により、これら2つはプロダクトの使いやすさ・セキュリティ・成長に直接関わっています。基礎を理解することで、次のことができます:
- 最初から安全な機能設計ができる
- エンジニアリングチームと効果的にコミュニケーションできる
- 認証・ユーザーフローに関してより良いプロダクト判断ができる
- ユーザーの信頼を失うような高コストなセキュリティ上のミスを回避できる
例えば、最新の MCP仕様 では、認可システムは信頼性のある標準に基づいて構築されています:
- OAuth 2.1 IETF Draft (draft-ietf-oauth-v2-1-13)
- OAuth 2.0 Authorization Server Metadata (RFC8414)
- OAuth 2.0 Dynamic Client Registration Protocol (RFC7591)
- OAuth 2.0 Protected Resource Metadata (RFC9728)
なぜ重要なのか
たとえバックエンドコードを書かなくても:
- 開発者は API のセキュリティ確保・セッション管理・サードパーティサービスとの連携手法を学べます。
- プロダクトマネージャーは、ログインフロー・連携・コンプライアンスについてチームやパートナーと議論できる語彙を獲得できます。
- 創業者やスタートアップチームは、連携時に破綻したり脆弱になるログインシステムの構築を回避できます。
JWT vs OAuth:2つの基本概念
JWT(JSON Web Token)と OAuth(Open Authorization)はよくセットで用いられますが、それぞれ役割が異なります。
例えるなら:
- OAuth は「 鍵を誰かに渡す方法 」で、許可された部屋にだけアクセス可能です。
- JWT はその「 ID カード 」であり、本人が誰で何ができるかの証明です。
次のセクションで対比しながら、それぞれの違いと補完関係を明確に説明します。
OAuth 2.0 とは?
OAuth 2.0 は、アプリケーション(クライアント)がユーザーのリソースへ限定的な権限でアクセスする際、ユーザーの認証情報(パスワードなど)を共有することなくアクセスを可能とする広く採用されている 認可フレームワーク です。
OAuth の主要な役割
- クライアント: アクセスを要求するアプリケーション
- リソースオーナー: 通常はユーザー、許可を与える本人
- 認可サーバー: 認可後にアクセストークンを発行
- リソースサーバー: 保護リソースをホストし、トークンを検証
よく使われる OAuth のグラントタイプ(フロー)
- 認可コードグラント: 最も安全で推奨。ブラウザ、SPA、モバイルアプリで PKCE と併用。
- インプリシットグラント: OAuth 2.1 ではセキュリティ上の理由から非推奨。
- リソースオーナーパスワードクレデンシャル(ROPC): ユーザー名・パスワードを直接使ってトークン発行。安全性は低い。
- クライアントクレデンシャルグラント: サーバー間や機械間通信向け。
- デバイスフロー: スマートTVなど入力装置のないデバイスで、2台目デバイスから認可。
JWT(JSON Web Token)とは?
JWT は、2者間で主張(クレーム)を安全に、かつコンパクト・URL安全な方法で送るためのオープンスタンダード(RFC 7519)です。
JWT の構造
JWT は3つの base64url エンコードされた部分(. で区切られる)で構成されます:
- ヘッダー: アルゴリズム(例:HS256、RS256)とトークンタイプ(JWT)を指定
- ペイロード: 以下のようなクレームを含む
- iss(発行者)
- sub(サブジェクト、例:ユーザーID)
- aud(オーディエンス)
- exp(有効期限)
- 必要に応じたカスタムクレーム
- 署名 – トークンの改ざんがないか検証
例:
JWT の例
典型的な JWT をエンコード形式とデコードした構造で紹介します。各パートが何を表しているか一目で分かります。
エンコードされたJWT(Base64URL)
3つの部分がドット区切りで構成されています:header.payload.signature
デコードした構造
- ヘッダー
- ペイロード
ペイロードには クレーム が含まれます。
- 署名
署名によってトークンの改ざんが防止されます。
主な特徴
- 自己完結型: 必要な情報が全てトークン内に含まれる
- ステートレス: サーバー側でセッションストレージが不要
- 署名付き: (オプションで暗号化も)真正性を保証
JWT vs OAuth:主な違い
項目 | JWT | OAuth 2.0 |
---|---|---|
定義 | トークンフォーマット | 認可フレームワーク |
目的 | ID・クレームを安全に運ぶ | アクセス管理・認可方法定義 |
範囲 | データ表現 | プロセスとフロー |
単体利用可? | 内部トークン管理なら可 | 不可、トークン形式(例:JWT)が必要 |
利用例 | API がクライアントにJWTを直接発行 | アプリがOAuthフローでアクセストークン取得 |
まとめ:
- JWT は「入れ物」: パスポートのようにIDの詳細を含む
- OAuth は「システム」: 入国管理のように、パスポートを誰にどこまで許すか決める
JWTを単体で使うべき場合
以下のようなケースはJWT単体利用が適しています:
- 単一システム認証:外部IDプロバイダーを使わず、アプリ自身がトークンを発行・検証
- ステートレスなセッション管理:サーバー側にセッションデータを保持せず、認証を行う
- シンプルなAPI認証:複雑な同意フローが不要な、内部APIのアクセス権確認など
- パフォーマンス重視の検証:リソースサーバーが認証サーバーに問い合わせずトークンをローカル検証
例:
自社のシングルページアプリとバックエンドAPI。APIがsub(ユーザーID)、role、および exp(有効期限)クレームを持つJWTを発行。
OAuthのみを使うべき場合
次のような場合はJWTではなくOAuth単体利用が妥当です:
- 自己完結型トークンが不要で、都度照会が必要な不透明トークンで問題ない場合
- リソースサーバーが毎回認可サーバーにアクセス権検証を行いたい場合
- JWTが適さないレガシーや規制環境
- サードパーティアプリに限定的権限を委任して安全にアクセスさせることが目的のとき
例:
アクセストークンを不透明な形式で発行し、リクエストごとに認可サーバーに問い合わせて検証するAPI。
JWTとOAuthを両方使うべき場合
両方同時利用が適しているのは:
- 複数サービス/ API で OAuth による安全な認可フロー・JWT による検証可能なトークン運用が必要なとき
- 「Googleでログイン」など、OAuth で同意処理・JWT でアクセス/ID トークンを運ぶ場合
- マイクロサービスアーキテクチャで各サービスが JWT をローカル検証したい場合
- OAuth の委譲モデルと JWT のステートレス検証によるスケーラビリティが必要な場合
例:
アプリで Google ログインを採用。OAuth が認可処理を担当し、Google がJWTアクセス(またはID)トークンを発行、APIがそれをローカル検証してデータ返却。
JWT と OAuth の連携イメージ
現代的な認証・認可構成において:
- OAuth がアクセス許可のフローを担当
- 認可サーバー がアクセストークン(多くの場合JWT)を発行
- JWT がAPIリクエスト時に「本人性」「権限」を証明
OAuth の特別なトークン
JWTとOAuthのベストプラクティス
- HTTPSを利用してトークンの盗聴を防ぐ
- JWTの有効期限を短く設定し、 長期セッションはリフレッシュトークンを利用
- 署名を検証し クレームを盲信しない
- audクレームを確認し、 トークンが自分のアプリ向けか検証する
- XSSリスクがある場合はトークンを localStorage に保存しない。 セキュアなクッキーを推奨
まとめ
- OAuth 2.0 は「トークンの取得・利用方法」を規定
- JWT は「トークンのフォーマット・情報の運び方」を規定
- 両者は 相補的 であり、置き換え可能ではありません。
現代のAPIの多くは、認可フローにOAuth、トークンの表現にJWTを利用しています。両方を理解することで、安全でスケーラブルな認証認可システムを設計できるようになります。