C
ネットワーク/認証/Lesson 06

認証 — Cookie・セッション・JWT・OAuth

45分·theory

認証 — Cookie・セッション・JWT・OAuth

🎯 このlessonを読み終えたら

このlessonを読み終えると、次の3つを自信を持って説明できるようになります。

  • ✅ Cookie・Session・JWTの違い
  • ✅ OAuth 2.0 Authorization Code Flow + PKCE
  • ✅ Access TokenとRefresh Tokenの運用

学習目標をチェックリストとして手元に置き、すべてに答えられるようになったらlessonを閉じてください。

Cookie + セッション

Cookie = ブラウザに保存される小さなデータ。サーバーがSet-Cookieヘッダーで発行します。

Cookieの属性:

code
Set-Cookie: session=abc123;
  HttpOnly;          # JS からアクセス不可 (XSS 防御)
  Secure;            # HTTPS でのみ送信
  SameSite=Lax;      # CSRF 防御 (外部サイトからブロック)
  Max-Age=86400;     # 1日
  Path=/;
  Domain=.example.com;

SameSiteオプション:

  • Strict — 外部サイトからすべてブロック(最も安全、UXに影響あり)
  • Lax — GETなど安全なメソッドのみ許可(デフォルト推奨)
  • None — すべて許可(Secureフラグ必須)

セッション認証(サーバーサイド保存):

code
1. POST /login (メール+パスワード)
2. サーバー: 検証 → sessionId 生成 → Redis に保存
   { "sess:abc123": { userId: 42, exp: ... } }
3. 応答: Set-Cookie: session=abc123 (HttpOnly)
4. 以降のリクエスト: ブラウザが自動添付
5. サーバー: sessionId → Redis 検索 → user
6. ログアウト: Redis 削除 → 即時無効

メリット:

  • 即時無効化が可能
  • 軽量なCookie(sessionIdのみ)
  • HttpOnlyによるXSS対策

デメリット:

  • サーバーサイドのストレージが必要(Redis推奨)
  • マルチサーバー環境ではスティッキーセッションまたは共有ストレージが必要
  • モバイルアプリ・SPAでの扱いが複雑

JWT — 自己検証トークン

JWT (JSON Web Token)Statelessな認証方式:

構造.で区切られた3つのパート):

code
xxxx.yyyy.zzzz
└┬─┘ └┬─┘ └┬─┘
Header  │   Signature
     Payload

Base64デコード後:

json
// Header
{ "alg": "HS256", "typ": "JWT" }

// Payload (claims)
{
  "sub": "42",                  // subject (user id)
  "exp": 1735689600,            // 期限
  "iat": 1735603200,            // 発行時刻
  "role": "admin"               // カスタム
}

// Signature = HMAC-SHA256(header.payload, secret)

サーバーによる検証:
1. トークンを分解 → header.payload.sig
2. HMAC-SHA256(header.payload, secret) を再計算
3. 受け取ったsigと一致? → 改ざんなし
4. expより前? → 有効
5. payloadのユーザー情報を信頼

メリット:

  • サーバーストレージ不要(stateless)
  • マルチサーバー・MSAに親和性が高い
  • モバイル・SPA向けにクリーン(Authorizationヘッダー)

デメリット:

  • 無効化が困難 — expまで有効(Redisブラックリストが必要)
  • トークンサイズ(約200〜500バイト)
  • 秘密鍵が漏洩した場合、全体が危険にさらされる
  • LocalStorage保存 = XSSリスク → httpOnly Cookieを推奨

Access + Refreshトークンパターン(最も一般的):

  • Access Token: 15分、頻繁に使用
  • Refresh Token: 7日間、更新専用(httpOnly + Secure)
  • Access Token期限切れ時 → Refresh Tokenで新しいAccess Tokenを発行
  • Refresh Tokenも期限切れ → 再ログインが必要

OAuth 2.0 + OIDC

OAuth 2.0 = 他のサービスへの認証委譲。「Googleでログイン」の標準プロトコル。

Authorization Code Flow(最も安全、サーバーアプリ向け):

code
1. ユーザー: "Googleでログイン"クリック
2. 私たちのアプリ → Google: ログインページにリダイレクト
   https://accounts.google.com/o/oauth2/auth?
     client_id=xxx&redirect_uri=https://us/cb&response_type=code&scope=email

3. ユーザーがGoogleにログイン + 同意
4. Google → 私たちのコールバック: code=ABC

5. 私たちのサーバー → Google: codeを交換 (server-to-server)
   POST /oauth/token
   { code: 'ABC', client_id, client_secret }

6. Google → 私たちのサーバー: access_token + refresh_token

7. 私たちのサーバー: tokenでGoogle APIを呼び出し
   GET /userinfo (名前・メールアドレス)

8. 私たちのDBにユーザーをマッピング・ログイン

PKCE(Proof Key for Code Exchange):

  • モバイルアプリ・SPAのようにclient_secretを隠せない場合に使用
  • クライアントがcode_verifierを生成
  • ステップ1: code_challenge = SHA256(code_verifier) を送信
  • ステップ5: code_verifier を送信 → Googleが検証
  • 2025年標準 — サーバーアプリにも推奨

OAuthスコープ — 権限範囲:

  • email — メールアドレス
  • profile — 名前・プロフィール写真
  • read:repos — GitHubリポジトリの読み取り
  • 最小権限の原則(必要なものだけリクエスト)

OIDC(OpenID Connect) = OAuth 2.0 + 認証標準:

  • OAuth = 認可(authorization)
  • OIDC = OAuth + 認証(authentication)
  • id_token(JWT)を追加 — ユーザーの身元情報を含む
  • Google・Naver・Kakao・Apple Sign-InはすべてOIDCを採用

代表的なライブラリ:

  • NextAuth.js(Next.js)
  • Spring Security OAuth2 Client
  • Passport.js(Express)
  • Auth0・Clerk・Supabase Auth(マネージドサービス)

🤖 AIにこう依頼してみましょう

このlessonの概念を理解すると、AIに具体的な指示を出せるようになります。漠然と「直して」と頼むのではなく、語彙を持ったリクエストで伝える — それがトークン節約の第一歩です。

  • 「このセッション認証をJWTに移行して」
  • 「このOAuth 2.0フローにPKCEを追加して」

なぜこれがトークンを減らすのか

概念を知らないままAIの回答を受け取ると、「それは何ですか?」と再度聞き返す必要があります。その「聞き返し」がトークンを消費します。概念を一度しっかり学んでおけば、会話が一度で完結します。

認証 — Cookie・セッション・JWT・OAuth - ネットワーク