1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【図解でわかるWeb技術③】OAuth 2.0 の仕組み ― 「Googleでログイン」の裏側

1
Last updated at Posted at 2026-03-30

はじめに

「Googleでログイン」「GitHubでログイン」

日常的に使っているこのボタン、裏側で何が起きているか 説明できますか?

実はこのボタンの裏では OAuth 2.0 というプロトコルが動いています。OAuth 2.0 を理解すると、認証・認可の設計が格段にクリアになります。

この記事では、OAuth 2.0 の中でも最も安全とされる 認可コードフロー を中心に、図解で一歩ずつ解説します。

この記事は 「図解でわかるWeb技術の仕組み」シリーズ の第3回です。
第2回:Cookie・Session・JWTの違いを先に読むと、よりスムーズに理解できます。


1. OAuth 2.0 とは

認証と認可の違い

まず、混同しやすい2つの概念を整理します。

意味 英語
認証 「あなたは誰?」を確認する Authentication ログイン(ID/パスワード)
認可 「何をしていいか」を許可する Authorization 「プロフィール情報の読み取りを許可」

OAuth 2.0 は「認可」の仕組みです。 「認証」ではありません。

「OAuth = ログイン」は厳密には間違い
OAuth 2.0 自体はログイン(認証)の仕様ではなく、「データへのアクセス権を委譲する」仕様です。ログイン機能として使う場合は、OAuth 2.0 の上に構築された OpenID Connect(OIDC) を使います。

OAuth 2.0 の全体像

03_oauth_overview.png

OAuth 2.0 の登場人物は 4つのロール です。

ロール 役割 具体例
リソースオーナー データの持ち主 ユーザー(あなた)
クライアント データを使いたいアプリ 第三者のWebアプリ
認可サーバー 許可を出す窓口 Google, GitHub
リソースサーバー 実際のデータを持つサーバー Google API, GitHub API

2. 認可コードフロー ― OAuth 2.0 の標準パターン

OAuth 2.0 にはいくつかのフローがありますが、最もセキュアで推奨される のが 認可コードフロー(Authorization Code Flow) です。

03_oauth_auth_code_flow.png

フローの詳細

STEP 1: 認可リクエスト

https://accounts.google.com/o/oauth2/v2/auth?
  response_type=code
  &client_id=YOUR_CLIENT_ID
  &redirect_uri=https://myapp.com/callback
  &scope=profile email
  &state=xyz123
パラメータ 意味
response_type=code 認可コードを要求する
client_id アプリの識別子(事前に登録)
redirect_uri 認可後のリダイレクト先
scope アクセスしたい範囲
state CSRF対策のランダム文字列

STEP 2: トークン取得

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

grant_type=authorization_code
&code=AUTHORIZATION_CODE
&redirect_uri=https://myapp.com/callback
&client_id=YOUR_CLIENT_ID
&client_secret=YOUR_CLIENT_SECRET

認可コードは 1回だけ使えるワンタイムコード です。使用後は無効になります。

STEP 3: リソースアクセス

GET /userinfo HTTP/1.1
Authorization: Bearer ACCESS_TOKEN

3. アクセストークンとリフレッシュトークン

03_oauth_tokens.png

なぜ2種類のトークンがあるのか

セキュリティと利便性のバランスを取るためです。

アクセストークンだけの場合:
├── 有効期限を長くする → 漏洩時の被害が大きい
└── 有効期限を短くする → 頻繁に再ログインが必要

解決策: 2種類のトークンを使い分ける
├── アクセストークン → 短命(15分〜1時間)で頻繁に使う
└── リフレッシュトークン → 長命で、新しいアクセストークンの発行にのみ使う

リフレッシュトークンの流れ

# アクセストークンが期限切れ → 401 Unauthorized

# リフレッシュトークンで新しいアクセストークンを取得
POST /token HTTP/1.1
Content-Type: application/x-www-form-urlencoded

grant_type=refresh_token
&refresh_token=REFRESH_TOKEN
&client_id=YOUR_CLIENT_ID
&client_secret=YOUR_CLIENT_SECRET

リフレッシュトークンのローテーション
セキュリティをさらに高めるため、リフレッシュトークンを使うたびに新しいリフレッシュトークンも一緒に発行する(古いものは無効化する)パターンが推奨されています。


4. スコープ(scope)― アクセス範囲を制限する

03_oauth_scope.png

スコープは 「何に対するアクセスを許可するか」 を細かく制御する仕組みです。

スコープのリクエスト例

scope=profile email  → プロフィールとメールだけ読める
scope=repo           → リポジトリの読み書き
scope=read:user      → ユーザー情報の読み取りのみ

最小権限の原則

スコープは必要最小限にする
アプリが「プロフィール情報」しか必要ないのに scope=repo(リポジトリの読み書き)を要求すると、ユーザーの信頼を失います。必要な権限だけを要求する のがOAuth 2.0の正しい使い方です。


5. セキュリティ対策

03_oauth_security.png

PKCE(Proof Key for Code Exchange)

PKCEは特にSPAやモバイルアプリで必須のセキュリティ対策です。

// 1. ランダムな code_verifier を生成
const codeVerifier = generateRandomString(128);

// 2. SHA-256ハッシュを取って code_challenge を作成
const codeChallenge = base64url(sha256(codeVerifier));

// 3. 認可リクエストに code_challenge を含める
const authUrl = `https://auth.example.com/authorize?
  response_type=code
  &client_id=YOUR_CLIENT_ID
  &code_challenge=${codeChallenge}
  &code_challenge_method=S256`;

// 4. トークンリクエストに code_verifier を含める
const tokenResponse = await fetch('/token', {
  method: 'POST',
  body: new URLSearchParams({
    grant_type: 'authorization_code',
    code: authorizationCode,
    code_verifier: codeVerifier  // ← 元の値を送る
  })
});

state パラメータ

// リクエスト時: ランダムな state を生成して保存
const state = generateRandomString(32);
sessionStorage.setItem('oauth_state', state);

// コールバック時: state が一致するか検証
const returnedState = new URL(window.location).searchParams.get('state');
if (returnedState !== sessionStorage.getItem('oauth_state')) {
  throw new Error('CSRF攻撃の可能性');
}

6. OAuth 2.0 のフロー一覧

認可コードフロー以外にもフローがありますが、現在は 認可コードフロー + PKCE が推奨されています。

フロー 特徴 推奨度
認可コードフロー サーバーサイドアプリ向け。最もセキュア 推奨
認可コード + PKCE SPA・モバイルアプリ向け。client_secret 不要 推奨
インプリシットフロー SPA向けだったが、トークンがURLに露出する 非推奨
クライアントクレデンシャル マシン間通信向け(ユーザー関与なし) 用途次第
リソースオーナーパスワード パスワードを直接渡す。OAuth以前の方式 非推奨

インプリシットフローは使わない
かつてはSPA向けに推奨されていましたが、アクセストークンがURLフラグメントに露出するため、現在は 認可コードフロー + PKCE に置き換えられています。


7. 実務での使いどころ

「Googleでログイン」の実装例(概要)

1. Google Cloud Console でOAuthクライアントIDを取得
2. ユーザーをGoogleの認可エンドポイントにリダイレクト
3. ユーザーが同意 → 認可コードが返る
4. 認可コードをトークンと交換
5. アクセストークンで Google UserInfo API を呼ぶ
6. メールアドレスで自アプリのユーザーと紐付け

よくあるミス

ミス 正しい対応
state パラメータを省略 必ず検証する(CSRF対策)
redirect_uri を検証しない 完全一致で検証する
アクセストークンをlocalStorageに保存 HttpOnly Cookie に格納する
スコープを広く取りすぎる 必要最小限にする

8. まとめ

項目 ポイント
OAuth 2.0 の目的 パスワードを渡さずにデータアクセスを委譲する「認可」の仕組み
認可コードフロー 認可コード → トークン交換の2段階方式。最もセキュア
アクセストークン リソースへのアクセス許可証。短命(15分〜1時間)
リフレッシュトークン アクセストークンの再発行用。長命で認可サーバーにのみ送信
スコープ アクセス範囲の制限。最小権限の原則を守る
PKCE 認可コードの横取り防止。SPA・モバイルでは必須

次回予告

第4回では 「DNS解決の流れ」 を図解で解説します。ブラウザに example.com と入力してからIPアドレスが返ってくるまで、裏側で何が起きているのか ― 再帰的問い合わせとキャッシュの仕組みをたどります。


シリーズ目次

# テーマ
1 HTTPリクエスト/レスポンスの仕組み
2 Cookie・Session・JWTの違い
3 OAuth 2.0 の仕組み(この記事)
4 DNS解決の流れ
5 HTTPS・TLS通信の仕組み
6 CDN の仕組みと役割
7 WebSocket ― 双方向リアルタイム通信
8 キャッシュ戦略(ブラウザ・サーバー・CDN)
9 CORS ― クロスオリジンの壁を理解する
10 REST API 設計の基本原則

「この記事が役に立った」と思ったら、LGTM とストックをお願いします。

@kotaro_ai_lab
AI活用や開発効率化について発信しています。フォローお気軽にどうぞ!

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?