メインコンテンツまでスキップ

RFC 6749: OAuth 2.0 認可フレームワーク

RFC 6749 は OAuth 2.0 の基本仕様です。このドキュメントでは、OAuth 2.0 の概念から各認可フローまでを解説します。


第1部: 概要編

OAuth 2.0 とは何か?

OAuth 2.0 は、サードパーティアプリケーションがユーザーのリソースに安全にアクセスするための認可フレームワークです。

重要なポイント:認可(Authorization) であり、認証(Authentication) ではありません。

なぜ OAuth 2.0 が必要なのか?

OAuth 2.0 以前は、サードパーティアプリがユーザーのリソースにアクセスするには、ユーザーのパスワードを直接受け取る必要がありました。

問題説明
パスワード共有ユーザーがサードパーティにパスワードを教える必要がある
過剰な権限サードパーティがユーザーの全権限を持ってしまう
取り消し不可特定のアプリだけアクセスを取り消すことが困難
セキュリティリスクパスワード漏洩時の影響が甚大

OAuth 2.0 は、アクセストークンという有効期限付きの限定的な権限を付与することで、これらの問題を解決します。

4つの登場人物(ロール)

OAuth 2.0 には 4 つのロールが登場します。

┌─────────────────┐      ┌─────────────────┐
│ Resource Owner │ │ Client │
│ (ユーザー) │ │ (アプリ) │
└────────┬────────┘ └────────┬────────┘
│ 認可 │ トークン要求
▼ ▼
┌─────────────────┐ ┌─────────────────┐
│ Authorization │◄────►│ Resource │
│ Server │ │ Server │
│ (認可サーバー) │ │ (リソースサーバー) │
└─────────────────┘ └─────────────────┘
ロール説明
Resource Owner保護されたリソースの所有者エンドユーザー
ClientリソースにアクセスしたいアプリケーションWebアプリ、モバイルアプリ
Authorization Serverアクセストークンを発行するサーバーGoogle OAuth, Auth0
Resource Server保護されたリソースをホストするサーバーGoogle API, GitHub API

4つの認可グラント

OAuth 2.0 では、アクセストークンを取得する方法として 4 つのグラントタイプが定義されています。

グラント用途推奨度
Authorization CodeWebアプリ、モバイルアプリ✅ 推奨
ImplicitSPA(非推奨)❌ 非推奨
Resource Owner Password高信頼クライアント(レガシー)⚠️ 限定的
Client Credentialsサーバー間通信✅ 推奨

現代の OAuth 2.0 では、Authorization Code Grant + PKCE が標準です。


第2部: 詳細編

Authorization Code Grant

最も一般的で推奨されるフローです。

フロー図

     ┌──────┐                               ┌───────────────┐
│User │ │Authorization │
│Agent │ │ Server │
└──┬───┘ └───────┬───────┘
│ │
│ (1) Authorization Request │
│ (/authorize?response_type=code&...) │
│ ─────────────────────────────────────────►│
│ │
│ (2) User Authentication & Consent │
│ ◄────────────────────────────────────────►│
│ │
│ (3) Authorization Response │
│ (redirect_uri?code=xxx&state=yyy) │
│ ◄─────────────────────────────────────────│
│ │
┌──┴───┐ ┌───────┴───────┐
│Client│ │Authorization │
│ │ │ Server │
└──┬───┘ └───────┬───────┘
│ │
│ (4) Token Request │
│ (POST /token, grant_type=authorization_ │
│ code, code=xxx) │
│ ─────────────────────────────────────────►│
│ │
│ (5) Token Response │
│ (access_token, refresh_token, ...) │
│ ◄─────────────────────────────────────────│
│ │

認可リクエスト(Authorization Request)

GET /authorize?
response_type=code
&client_id=s6BhdRkqt3
&redirect_uri=https%3A%2F%2Fclient.example.org%2Fcallback
&scope=read%20write
&state=xyz123
HTTP/1.1
Host: auth.example.com
パラメータ必須説明
response_typecode を指定
client_idクライアント識別子
redirect_uriコールバック URL(事前登録必須)
scope要求するスコープ(スペース区切り)
state推奨CSRF 対策用のランダム値

認可レスポンス(Authorization Response)

成功時:

HTTP/1.1 302 Found
Location: https://client.example.org/callback?
code=SplxlOBeZQQYbYS6WxSbIA
&state=xyz123

エラー時:

HTTP/1.1 302 Found
Location: https://client.example.org/callback?
error=access_denied
&error_description=The%20resource%20owner%20denied%20the%20request
&state=xyz123
エラーコード説明
invalid_requestリクエストパラメータが不正
unauthorized_clientクライアントが認可されていない
access_deniedユーザーが拒否した
unsupported_response_typeサポートされていない response_type
invalid_scope不正なスコープ
server_errorサーバー内部エラー
temporarily_unavailable一時的に利用不可

トークンリクエスト(Token Request)

POST /token HTTP/1.1
Host: auth.example.com
Content-Type: application/x-www-form-urlencoded
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW

grant_type=authorization_code
&code=SplxlOBeZQQYbYS6WxSbIA
&redirect_uri=https%3A%2F%2Fclient.example.org%2Fcallback

トークンレスポンス(Token Response)

{
"access_token": "SlAV32hkKG",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "8xLOxBtZp8",
"scope": "read write"
}

Client Credentials Grant

サーバー間通信(Machine-to-Machine)で使用します。ユーザーの関与がないフローです。

POST /token HTTP/1.1
Host: auth.example.com
Content-Type: application/x-www-form-urlencoded
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW

grant_type=client_credentials
&scope=read

レスポンス:

{
"access_token": "2YotnFZFEjr1zCsicMWpAA",
"token_type": "Bearer",
"expires_in": 3600
}

注意: このフローでは refresh_token は発行されません。

Refresh Token の使用

アクセストークンの有効期限が切れた場合、リフレッシュトークンを使って新しいアクセストークンを取得できます。

POST /token HTTP/1.1
Host: auth.example.com
Content-Type: application/x-www-form-urlencoded
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW

grant_type=refresh_token
&refresh_token=8xLOxBtZp8

クライアントタイプ

OAuth 2.0 では、クライアントを機密性によって 2 種類に分類します。

タイプ説明
Confidentialクライアントシークレットを安全に保管できるサーバーサイド Web アプリ
Publicクライアントシークレットを安全に保管できないSPA、モバイルアプリ、デスクトップアプリ

Public クライアントでは、PKCE(RFC 7636) の使用が必須です。

スコープ(Scope)

スコープは、クライアントが要求するアクセス権限を表します。

scope=read write delete
  • スペース区切りで複数指定可能
  • 認可サーバーは要求されたスコープの一部のみを許可することも可能
  • トークンレスポンスの scope で実際に付与されたスコープが返される

セキュリティ考慮事項

RFC 6749 で言及されている主なセキュリティ対策:

対策説明
HTTPS 必須全ての通信を TLS で保護
state パラメータCSRF 攻撃の防止
redirect_uri の厳密な検証オープンリダイレクタ攻撃の防止
認可コードの一回限り使用リプレイ攻撃の防止
クライアント認証Confidential クライアントは必須

注意: RFC 6749 だけでは不十分です。現代のベストプラクティスは RFC 9700(OAuth 2.0 Security BCP)を参照してください。


参考リンク