LESSON 25分

ストーリー

高橋アーキテクト
認証は、セキュリティの最前線だ。誰がアクセスしているのか、本当にその人なのかを確認する仕組みだ

高橋アーキテクトが4つの認証方式を並べました。

高橋アーキテクト
セッション、JWT、OAuth2、OIDC。それぞれの特性を理解して、システムに最適な方式を選べるようになろう

セッションベース認証

サーバーサイドにセッション情報を保存し、クライアントにはセッションIDのみを渡す方式です。

// セッションベース認証のフロー
// 1. ログイン → サーバーがセッション作成 → Cookie にセッションID
// 2. リクエスト → Cookie のセッションID → サーバーでセッション検索
// 3. ログアウト → サーバーのセッション削除

import session from "express-session";
import RedisStore from "connect-redis";

app.use(session({
  store: new RedisStore({ client: redisClient }),
  secret: process.env.SESSION_SECRET!,
  resave: false,
  saveUninitialized: false,
  cookie: {
    secure: true,       // HTTPS のみ
    httpOnly: true,     // JavaScript からアクセス不可
    sameSite: "strict", // CSRF 対策
    maxAge: 30 * 60 * 1000, // 30分
  },
}));

JWT(JSON Web Token)認証

トークンに情報を含め、サーバーサイドにセッションを保存しないステートレスな方式です。

import jwt from "jsonwebtoken";

// JWTの構造: Header.Payload.Signature

interface JwtPayload {
  sub: string;     // ユーザーID
  role: string;    // ロール
  iat: number;     // 発行時刻
  exp: number;     // 有効期限
}

// トークン発行
const generateTokens = (userId: string, role: string) => {
  const accessToken = jwt.sign(
    { sub: userId, role },
    process.env.JWT_SECRET!,
    { expiresIn: "15m" } // アクセストークン: 短命
  );

  const refreshToken = jwt.sign(
    { sub: userId, type: "refresh" },
    process.env.JWT_REFRESH_SECRET!,
    { expiresIn: "7d" } // リフレッシュトークン: 長命
  );

  return { accessToken, refreshToken };
};

// トークン検証
const verifyToken = (token: string): JwtPayload => {
  return jwt.verify(token, process.env.JWT_SECRET!) as JwtPayload;
};

OAuth 2.0

第三者にリソースへのアクセスを委任するための認可フレームワークです。

// OAuth 2.0 Authorization Code Flow
// 1. ユーザー → 認可サーバーにリダイレクト
// 2. ユーザーが権限を許可
// 3. 認可サーバー → アプリに認可コードを返す
// 4. アプリ → 認可コードでアクセストークンを取得
// 5. アプリ → アクセストークンでリソースにアクセス

interface OAuth2Config {
  clientId: string;
  clientSecret: string;
  authorizationUrl: string;
  tokenUrl: string;
  redirectUri: string;
  scope: string[];
}

const googleOAuth: OAuth2Config = {
  clientId: process.env.GOOGLE_CLIENT_ID!,
  clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
  authorizationUrl: "https://accounts.google.com/o/oauth2/v2/auth",
  tokenUrl: "https://oauth2.googleapis.com/token",
  redirectUri: "https://myapp.com/auth/callback",
  scope: ["openid", "profile", "email"],
};

OpenID Connect (OIDC)

OAuth 2.0の上に認証レイヤーを追加した標準仕様です。IDトークンにより、ユーザーの身元情報を取得できます。

// OIDCはOAuth2にIDトークン(JWT)を追加
interface OidcTokenResponse {
  access_token: string;   // リソースアクセス用
  id_token: string;       // ユーザー情報を含むJWT
  refresh_token: string;  // トークン更新用
  token_type: "Bearer";
  expires_in: number;
}

// IDトークンのクレーム
interface IdTokenClaims {
  iss: string;   // 発行者
  sub: string;   // ユーザーID
  aud: string;   // クライアントID
  exp: number;   // 有効期限
  iat: number;   // 発行時刻
  email: string; // メールアドレス
  name: string;  // 氏名
}

認証方式の比較

項目セッションJWTOAuth2OIDC
ステートフル/レスステートフルステートレスステートレスステートレス
サーバー負荷セッション保存が必要検証のみ検証のみ検証のみ
スケーラビリティ低(セッション共有が必要)
リアルタイム無効化容易困難(ブラックリスト要)トークン失効で対応トークン失効で対応
用途従来のWebアプリAPI、SPA、モバイル第三者アクセス委任SSO、認証統合
CSRF対策必要不要(Bearerトークン)不要不要

選択の指針

ユースケース推奨方式
従来型Webアプリ(サーバーレンダリング)セッション
SPA + REST APIJWT
モバイルアプリJWT + OIDC
外部サービス連携OAuth2
シングルサインオン(SSO)OIDC
マイクロサービス間通信JWT(サービス間トークン)

まとめ

ポイント内容
セッションサーバーサイドで管理、CSRF対策が必要
JWTステートレスで拡張性が高い、無効化が課題
OAuth2アクセス委任の標準、認証には不十分
OIDCOAuth2 + 認証、SSOに最適

チェックリスト

  • セッションベース認証の仕組みを理解した
  • JWTの構造と利点・欠点を把握した
  • OAuth2の認可コードフローを理解した
  • OIDCとOAuth2の違いを説明できる

次のステップへ

次は「ゼロトラストアーキテクチャ」を学びます。従来の境界型セキュリティから、「何も信頼しない」新しいセキュリティモデルへの転換を理解しましょう。


推定読了時間: 25分