1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

JWTトークン方式と外部ストア方式(ローカルストレージ)を用いたログインステータス管理方法

Last updated at Posted at 2025-06-12

JWT(JSON Web Token)完全理解ガイド

1. JWTの基本構造

JWTは3つの部分から構成される文字列です:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIn0.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

構造: ヘッダー.ペイロード.署名

各部分の役割

部分 内容 エンコード方式 可逆性
ヘッダー アルゴリズム情報 Base64URL 可逆(デコード可能)
ペイロード ユーザー情報、有効期限等 Base64URL 可逆(デコード可能)
署名 改ざん検証用のハッシュ値 署名アルゴリズム依存 不可逆

具体例

// ヘッダー(JSON → Base64URL)
const header = {
  "alg": "HS256",  // アルゴリズム
  "typ": "JWT"     // トークンタイプ
};

// ペイロード(JSON → Base64URL)
const payload = {
  "user_id": 123,
  "name": "John Doe",
  "exp": 1672531200  // 有効期限
};

// 署名(ハッシュ値)
const signature = HMAC_SHA256(base64Url(header) + "." + base64Url(payload), secretKey);

2. 全体的なフロー

ログイン〜API利用までの流れ

クライアント側の処理

// 1. ログイン
const login = async (credentials) => {
  const response = await fetch('/api/login', {
    method: 'POST',
    body: JSON.stringify(credentials)
  });
  const { token } = await response.json();
  
  // 2. JWTをそのまま保存(一切変更しない)
  localStorage.setItem('jwt', token);
};

// 3. API呼び出し時
const callAPI = async () => {
  const token = localStorage.getItem('jwt');
  const response = await fetch('/api/protected', {
    headers: {
      'Authorization': `Bearer ${token}`  // そのまま送信
    }
  });
};

3. デジタル署名の仕組み

3.1 HMAC方式(対称鍵)

JWTで最も一般的な方式です。

特徴

  • 軽量: 処理が高速
  • シンプル: 鍵管理が簡単
  • 制限: 全サービスが同じ秘密鍵を共有する必要

3.2 RSA方式(非対称鍵)

マイクロサービス環境に適した方式です。

マイクロサービス環境での利点

利点:

  • 権限分離: 認証サーバーのみがJWT発行可能
  • セキュリティ: 公開鍵漏洩でもJWT作成不可
  • スケーラビリティ: 新サービス追加時は公開鍵配布のみ

4. 改ざん検出の仕組み

攻撃者が改ざんを試みた場合

ハッシュ関数の雪崩効果

// わずかな変更でも大きくハッシュ値が変化
const original = '{"user_id":123,"role":"user"}';
const modified = '{"user_id":123,"role":"admin"}'; // 1文字違い

const hash1 = SHA256(original);  // "a1b2c3d4e5f6..."
const hash2 = SHA256(modified);  // "x9y8z7w6v5u4..." (完全に異なる)

5. セキュリティ考慮事項

重要なポイント

  1. トークンの有効期限: 適切な期限設定でリスク軽減
  2. リフレッシュトークン: 長期間の認証維持
  3. XSS対策: CSP設定とhttpOnly Cookieの検討
  4. 鍵管理: 秘密鍵の厳重な管理

Vue.js + TypeScriptでの実装例

// composables/useAuth.ts
export const useAuth = () => {
  const isAuthenticated = ref(false);
  const user = ref<User | null>(null);

  const login = async (credentials: LoginCredentials) => {
    const response = await authAPI.login(credentials);
    const token = response.data.token;
    
    // JWTをそのまま保存
    localStorage.setItem('jwt-token', token);
    isAuthenticated.value = true;
    user.value = response.data.user;
  };

  const checkAuthStatus = () => {
    const token = localStorage.getItem('jwt-token');
    if (token && !isTokenExpired(token)) {
      isAuthenticated.value = true;
    }
  };

  return {
    isAuthenticated: readonly(isAuthenticated),
    user: readonly(user),
    login,
    checkAuthStatus
  };
};

6. まとめ

JWTの核心メカニズム

  1. ステートレス認証: サーバー側でセッション保持不要
  2. 改ざん検出: デジタル署名によるデータ整合性保証
  3. 権限分離: 認証サーバーと各サービスの責務分離
  4. スケーラビリティ: マイクロサービス環境に最適

理解のポイント

  • クライアント側: JWTを一切変更せず、そのまま保存・送信
  • サーバー側: 署名検証により改ざんの有無を確実に検出
  • セキュリティ: ハッシュ値の比較により、わずかな改ざんも検出可能
  • 実装: フロントエンドでの状態管理と適切なAPI呼び出し

JWTは「データの改ざん = ハッシュ値の変化 = 署名との不一致 = 改ざん検出」という連鎖により、堅牢なセキュリティを実現しています。

1
0
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
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?