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

License System Day 4: 商用グレードのアーキテクチャ設計パターン

Last updated at Posted at 2025-12-03

🎄 科学と神々株式会社 アドベントカレンダー 2025

License System Day 4: 商用グレードのアーキテクチャ設計パターン


📖 今日のテーマ

基礎編の最終回です。今日は「どのように設計するか?」というアーキテクチャ設計を学びます。

商用グレードのシステムは、セキュリティ、スケーラビリティ、メンテナンス性を考慮した設計が必要です。


🏗️ 基本アーキテクチャ: クライアント・サーバー型

全体像

┌──────────────────┐         HTTPS/TLS        ┌──────────────────┐
│                  │◄────────────────────────►│                  │
│  クライアント     │                           │  サーバー         │
│  (アプリ/CLI)    │  1. アクティベーション    │  (認証・認可)    │
│                  ├──────────────────────────►│                  │
│                  │                           │                  │
│                  │  2. ライセンスキー        │                  │
│                  │◄──────────────────────────┤                  │
│                  │                           │                  │
│                  │  3. サービス利用          │                  │
│                  ├──────────────────────────►│                  │
│                  │  + ライセンスキー          │                  │
│                  │                           │                  │
│                  │  4. レスポンス + 署名     │                  │
│                  │◄──────────────────────────┤                  │
│                  │                           │                  │
└──────────────────┘                           └──────────────────┘
       │                                              │
       │                                              │
       ▼                                              ▼
  公開鍵検証                                    秘密鍵署名
  (改ざん検知)                                  (データ保護)
                                                      │
                                                      ▼
                                              ┌──────────────┐
                                              │  データベース │
                                              │  - Users     │
                                              │  - Licenses  │
                                              │  - Logs      │
                                              └──────────────┘

🎯 設計の3大原則

1. セキュリティ・バイ・デザイン

「後から追加」ではなく「最初から組み込む」

❌ 悪い例:
  1. 機能を実装
  2. テスト
  3. リリース
  4. 「あ、セキュリティ忘れた!」← 手遅れ

✅ 良い例:
  1. セキュリティ要件定義
  2. セキュアな設計
  3. セキュアな実装
  4. セキュリティテスト
  5. リリース

2. 最小権限の原則

「必要最低限の権限だけを与える」

例: データベースアクセス

❌ すべてのユーザーが全テーブルにアクセス
  → データ漏洩のリスク

✅ 各ユーザーは自分のデータのみアクセス
  → 被害を最小化

3. 防御の多層化

「一つが破られても、次の防御がある」

Layer 1: HTTPS 暗号化
  ↓ (破られたとしても)
Layer 2: JWT 署名検証
  ↓ (破られたとしても)
Layer 3: レートリミット
  ↓ (破られたとしても)
Layer 4: 異常検知・ブロック

→ 一つの防御に頼らない!

🔐 セキュアな設計パターン

パターン1: 非対称鍵暗号

従来の方法(対称鍵):
  同じ鍵で暗号化・復号化
  ❌ 鍵を安全に共有できない

非対称鍵暗号:
  秘密鍵: サーバーのみ保持 → 署名作成
  公開鍵: クライアントに配布 → 署名検証
  ✅ 鍵を共有する必要がない!

具体例: ECDSA P-256

// サーバー側(署名)
const crypto = require('crypto');
const sign = crypto.createSign('SHA256');
sign.update(JSON.stringify(response));
const signature = sign.sign(privateKey, 'base64');

// クライアント側(検証)
const verify = crypto.createVerify('SHA256');
verify.update(JSON.stringify(response));
const isValid = verify.verify(publicKey, signature, 'base64');

if (!isValid) {
  throw new Error('改ざんされています!');
}

パターン2: JWT (JSON Web Token)

構造:
  Header.Payload.Signature

例:
  eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.
  eyJ1c2VyX2lkIjoiMTIzIiwicGxhbiI6InByZW1pdW0ifQ.
  MEUCIQDz7...

特徴:
  ✅ Stateless(サーバーで状態を持たない)
  ✅ 改ざん検知可能
  ✅ 有効期限設定可能

パターン3: レートリミット

目的:
  DDoS 攻撃防止
  API 乱用防止
  サーバー負荷軽減

実装:
  プラン別に制限設定
  ┌─────────────┬─────────┐
  │ Free        │ 10/時間 │
  │ Premium     │ 1000/時間│
  │ Enterprise  │ 無制限   │
  └─────────────┴─────────┘

保存先:
  - メモリ(Redis など)
  - データベース(SQLite など)

📊 データベース設計

階層構造

Users (ユーザー)
  ├─ user_id
  ├─ email
  ├─ password_hash  ← 平文保存は絶対NG!
  └─ created_at

    ↓ 1対多

Subscriptions (サブスクリプション)
  ├─ subscription_id
  ├─ user_id
  ├─ plan_type (free/premium/enterprise)
  ├─ status (active/expired/cancelled)
  └─ end_date

    ↓ 1対多

Licenses (ライセンス)
  ├─ license_id
  ├─ subscription_id
  ├─ activation_key (JWT)
  ├─ client_id (デバイス識別)
  └─ validation_count

正規化の重要性

❌ 悪い設計(正規化なし):
  Users テーブルに全部詰め込む
  ├─ user_id
  ├─ email
  ├─ plan_type
  ├─ license_key
  └─ ...

  問題:
    - データの重複
    - 更新時の不整合
    - スケールしにくい

✅ 良い設計(正規化):
  Users / Subscriptions / Licenses を分離

  利点:
    - データの一貫性
    - 柔軟な拡張
    - クエリの最適化

🚀 スケーラビリティの考え方

垂直スケーリング vs 水平スケーリング

垂直スケーリング(Scale Up):
  サーバーのスペックを上げる

  CPU: 2コア → 8コア
  RAM: 4GB → 32GB

  限界:
    物理的な上限がある
    コストが指数関数的に増加

水平スケーリング(Scale Out):
  サーバーの台数を増やす

  1台 → 10台 → 100台

  利点:
    理論上無限に拡張可能
    一台あたりのコストは一定

設計での考慮点

✅ Stateless 設計
  サーバーに状態を持たせない
  → どのサーバーでも同じ処理が可能
  → ロードバランサーで振り分け

✅ データベースの分離
  アプリケーションサーバーとDBを分離
  → それぞれ独立にスケール

✅ キャッシュの活用
  Redis などでキャッシュ
  → DB アクセスを減らす

🔄 API 設計のベストプラクティス

RESTful 設計

リソース指向:
  GET    /api/v1/users/:id        ユーザー取得
  POST   /api/v1/users             ユーザー作成
  PUT    /api/v1/users/:id        ユーザー更新
  DELETE /api/v1/users/:id        ユーザー削除

認証:
  POST   /api/v1/auth/login       ログイン
  POST   /api/v1/auth/logout      ログアウト

ライセンス:
  POST   /api/v1/license/activate アクティベーション
  GET    /api/v1/license/validate 検証
  POST   /api/v1/license/deactivate 無効化

バージョニング

URL ベース:
  /api/v1/...
  /api/v2/...

  利点: 分かりやすい
  欠点: URL が増える

ヘッダーベース:
  X-API-Version: 1
  X-API-Version: 2

  利点: URL がきれい
  欠点: ドキュメント化が必要

エラーレスポンス

{
  "error": {
    "code": "LICENSE_EXPIRED",
    "message": "ライセンスの有効期限が切れています",
    "details": {
      "expired_at": "2025-01-01T00:00:00Z",
      "plan": "premium"
    },
    "actions": [
      {
        "label": "更新する",
        "url": "/api/v1/license/renew"
      }
    ]
  }
}

🛡️ セキュリティチェックリスト

通信レベル

✅ HTTPS/TLS 1.3 の使用
✅ 証明書の検証
✅ 暗号スイートの選択
✅ HSTS ヘッダーの設定

アプリケーションレベル

✅ パスワードのハッシュ化(bcrypt/scrypt)
✅ SQL インジェクション対策
✅ XSS 対策
✅ CSRF 対策
✅ レートリミット
✅ 入力バリデーション

データベースレベル

✅ 最小権限のユーザー
✅ プリペアドステートメント
✅ バックアップの暗号化
✅ アクセスログの記録

📈 モニタリング・ロギング

何を記録するか

アクセスログ:
  - タイムスタンプ
  - IP アドレス
  - エンドポイント
  - レスポンスコード
  - レスポンス時間

エラーログ:
  - エラーの種類
  - スタックトレース
  - ユーザー情報
  - 再現手順

ビジネスログ:
  - ライセンス発行
  - プラン変更
  - 支払い情報

アラート設定

即座に対応が必要:
  - サーバーダウン
  - エラー率 > 5%
  - レスポンス時間 > 3秒

早めの対応が必要:
  - ディスク使用率 > 80%
  - CPU 使用率 > 70%
  - 不正アクセスの兆候

🎯 商用システムの事例研究

事例1: Stripe

特徴:
  - API ファーストの設計
  - 明確なエラーメッセージ
  - 豊富なドキュメント
  - Webhook による通知

学べること:
  - 開発者体験の重要性
  - テストモードの提供
  - バージョン管理の戦略

事例2: Twilio

特徴:
  - 使用量ベースの課金
  - リアルタイムダッシュボード
  - 多言語SDK

学べること:
  - 透明性の高い料金体系
  - 段階的な学習パス
  - コミュニティサポート

🌟 まとめ

商用グレードの設計で重要なこと:

  1. セキュリティ・バイ・デザイン

    • 最初から組み込む
    • 多層防御
  2. スケーラビリティ

    • Stateless 設計
    • 水平スケーリング
  3. API 設計

    • RESTful
    • バージョニング
    • 明確なエラー
  4. モニタリング

    • ログ記録
    • アラート設定
    • 継続的な改善

🎓 理解度チェック

  1. 非対称鍵暗号の利点は?
  2. JWT の構造は?
  3. 垂直・水平スケーリングの違いは?
  4. なぜ Stateless 設計が重要?

💡 次回予告

Day 5: 暗号化の基礎 - 対称鍵と非対称鍵

セキュリティ基礎編に突入!

  • 暗号化の歴史
  • 対称鍵暗号の仕組み
  • 非対称鍵暗号の仕組み
  • 実際のコード例

お楽しみに!


前回: Day 3: なぜライセンス認証が必要なのか
次回: Day 5: 暗号化の基礎 - 対称鍵と非対称鍵

Happy Learning! 🎉

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