OAuth 2.0

ユーザーのパスワードを渡さずに、リソースへの限定的なアクセスを許可する認可フレームワーク

認証セキュリティ

OAuth 2.0 とは

OAuth 2.0 は、RFC 6749 で定義された認可フレームワークである。ユーザーのパスワードをサードパーティのアプリに渡さずに、「このアプリはこのユーザーのこの範囲のデータを操作してよい」という許可だけを渡す。発行されたアクセストークンを API へ提示する方法は、RFC 6750 が Bearer トークンとして定めている。

名前の通り、OAuth 2.0 が扱うのは認可 (何にアクセスしてよいか) であって認証 (誰か) ではない。ここを混同すると設計を間違える。アクセストークンは持ち主が誰かを証明する道具ではなく、この範囲の操作を許されたという事実の証明にすぎない。したがってトークンを受け取れたことをログイン成功と読み替えると、別のアプリ向けに発行されたトークンを持ち込まれても区別できない。「Google でログイン」のように利用者の身元を受け取る用途は、OAuth 2.0 の上に認証の層を重ねた OpenID Connect (OIDC) が担う。

OAuth の登場人物

OAuth は登場人物を 4 つに分ける。分けること自体が仕組みの中心で、パスワードを知っているのは認可サーバーだけという状態を保ったまま、クライアントには期限と範囲を限ったトークンだけを渡せる。

役割説明
リソースオーナーデータの所有者ユーザー
クライアントアクセスを要求するアプリWeb アプリ
認可サーバートークンを発行Cognito, Google
リソースサーバーデータを提供する APIAPI Gateway + Lambda

認可コードフロー

代表的な認可コードフローの流れは次の通りである。

1. ユーザー → クライアント: 「ログインしたい」
2. クライアント → 認可サーバー: 認可リクエスト
3. ユーザー → 認可サーバー: ログイン + 同意
4. 認可サーバー → クライアント: 認可コード
5. クライアント → 認可サーバー: 認可コード + クライアントシークレット
6. 認可サーバー → クライアント: アクセストークン + リフレッシュトークン
7. クライアント → リソースサーバー: アクセストークンで API 呼び出し

トークンを 2 段階で受け取るのは、経路の性質が違うからである。4 の認可コードはブラウザのリダイレクト、つまり URL やログに残りやすい経路を通る。一方 5 と 6 のトークン交換はクライアントと認可サーバーの直接通信で行われる。そこで認可コードは短命かつ 1 回限りの引換券として設計され、盗まれても交換時の照合 (クライアントシークレット、シークレットを持てないクライアントなら PKCE) を通せなければトークンにはならない。

OAuth vs OIDC

OAuth 2.0 と OIDC の関係は、下から上への積み上げである。違いは ID トークンがあるかどうかに集約される。

観点OAuth 2.0OIDC
目的認可 (何にアクセスできるか)認証 (誰か) + 認可
トークンアクセストークンID トークン + アクセストークン
ユーザー情報標準化されていないID トークンに含まれる

OIDC の ID トークンは JWT で、誰が・いつ・どの認可サーバーで認証されたかが検証可能な形で入っている。対して OAuth 2.0 のアクセストークンは形式が規定されておらず、クライアントから見て中身の読めない文字列でも構わない。クライアントがアクセストークンを解析して身元を判断する前提にはなっていない。

グラントタイプ

グラントタイプは、クライアントがシークレットを安全に保管できるかどうかで選び分ける。

グラント用途
Authorization Codeサーバー側でシークレットを保持できる Web アプリ (PKCE の併用も推奨)
Authorization Code + PKCESPA・モバイルなどシークレットを隠せないクライアント (PKCE は必須)
Client Credentialsユーザーが介在しないサーバー間通信
Implicit使わない (RFC 9700 で SHOULD NOT)
Resource Owner Password使わない (RFC 9700 で MUST NOT)

「非推奨」の強さは同じではない。RFC 9700 (2025 年 1 月・BCP 240・RFC 6749 と RFC 6750 を更新) は、認可レスポンスでアクセストークンを直接返す Implicit については使うべきでない (SHOULD NOT)、リソースオーナーパスワードクレデンシャルについては使ってはならない (MUST NOT) と書き分けている。前者は漏れたトークンをそのまま使われる経路を塞ぐ標準的な手段がないため、後者はユーザーのパスワードがクライアントを経由してしまうためである。PKCE (RFC 7636) は、シークレットを隠せない公開クライアントでは必須、シークレットを持てるクライアントでも推奨とされている。これらの慣行を本文に取り込んだ OAuth 2.1 は、2026 年 8 月時点ではまだ Internet-Draft (draft-ietf-oauth-v2-1) の段階で、RFC 番号は付いていない。

実装で迷ったときの判断は 2 つに絞れる。シークレットを安全に置ける場所があるかどうかでクライアントの種別を決め、その上で認可コードフローに PKCE を付けるかどうかを決める。ここを外さなければ、残りは各認可サーバーの設定差の話に収まる。

この記事は役に立ちましたか?

関連用語

関連する記事