# 機能設計書 34-APIトークン管理

## 概要

本ドキュメントは、InvenTreeシステムにおけるAPIトークン管理機能の設計を定義する。REST APIアクセスに使用するトークンの作成・管理・失効を行う機能を提供する。

### 本機能の処理概要

APIトークン管理機能は、外部システムやスクリプトからInvenTree REST APIにアクセスするための認証トークンを管理する。ユーザーごとに複数のトークンを発行・管理でき、有効期限や名前による識別が可能。

**業務上の目的・背景**：在庫管理システムは、ERPシステムやバーコードスキャナー、自動化スクリプトなど外部システムとの連携が多い。これらの連携においてセキュアなAPI認証を提供するため、ユーザーごとのAPIトークン管理が必要となる。

**機能の利用シーン**：
- 外部システム連携のためのAPIトークン発行
- 自動化スクリプト用の長期トークン作成
- セキュリティ対策としてのトークン定期更新
- 漏洩時のトークン即座の失効
- トークンの有効期限管理

**主要な処理内容**：
1. APIトークンの生成（ユーザー固有のトークン文字列）
2. トークン情報の保存（名前、有効期限、最終使用日時）
3. トークンによるAPI認証
4. トークンの失効（削除）
5. トークン一覧の管理

**関連システム・外部連携**：
- REST APIエンドポイント
- Django REST Framework Token認証
- 外部システム（ERP、バーコードスキャナー等）

**権限による制御**：
- トークン作成・管理は認証済みユーザーが自身のトークンのみ操作可能
- 他ユーザーのトークンへのアクセスは不可
- スーパーユーザーはすべてのトークンを閲覧可能

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 36 | ユーザー設定画面 | 主画面 | APIトークン管理パネルでの操作 |
| 34 | 管理センター画面 | 参照画面 | システム全体のトークン管理（スーパーユーザー） |

## 機能種別

CRUD操作 / セキュリティ管理

## 入力仕様

### トークン作成入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| name | str | No | トークン名 | 100文字以内 |
| expiry | date | No | 有効期限日 | 未来日付 |
| active | bool | No | 有効状態 | true/false（デフォルトtrue） |
| revoked | bool | No | 失効状態 | true/false（デフォルトfalse） |

### 入力データソース

- ユーザー設定画面からのフォーム入力
- REST API経由のJSON入力

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| pk | int | トークンID（主キー） |
| token | str | トークン文字列（生成時のみ表示） |
| name | str | トークン名 |
| created | datetime | 作成日時 |
| expiry | date | 有効期限日 |
| last_seen | datetime | 最終使用日時 |
| active | bool | 有効状態 |
| revoked | bool | 失効状態 |

### 出力先

- REST APIレスポンス（JSON）
- ユーザー設定画面への表示
- データベース（users_apitoken）

## 処理フロー

### 処理シーケンス

```
1. トークン作成リクエスト受信
   └─ ユーザー認証確認
2. トークン文字列生成
   └─ ランダムな文字列を生成
3. トークン情報保存
   └─ ApiTokenモデルへの保存
4. トークン文字列をハッシュ化
   └─ 保存用に不可逆ハッシュ化
5. レスポンス返却
   └─ トークン文字列を一度だけ表示
```

### フローチャート

```mermaid
flowchart TD
    A[トークン作成リクエスト] --> B{ユーザー認証済み?}
    B -->|No| C[401エラー]
    B -->|Yes| D[トークン文字列生成]
    D --> E[トークン情報保存]
    E --> F[トークン文字列ハッシュ化]
    F --> G[レスポンス返却]
    G --> H[※トークンは一度だけ表示]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-34-01 | トークン一度表示 | 生成されたトークン文字列は作成時のみ表示可能 | トークン生成時 |
| BR-34-02 | 有効期限チェック | expiryを過ぎたトークンは認証に失敗 | API認証時 |
| BR-34-03 | 失効トークン無効 | revokedがtrueのトークンは認証に失敗 | API認証時 |
| BR-34-04 | アクティブチェック | activeがfalseのトークンは認証に失敗 | API認証時 |
| BR-34-05 | ユーザースコープ | ユーザーは自身のトークンのみ操作可能 | トークン操作時 |

### 計算ロジック

トークン有効性判定:
```python
is_valid = token.active and not token.revoked and (
    token.expiry is None or token.expiry >= date.today()
)
```

## データベース操作仕様

### 操作別データベース影響一覧

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| トークン作成 | users_apitoken | INSERT | トークンレコード作成 |
| トークン更新 | users_apitoken | UPDATE | 名前、有効期限、状態更新 |
| トークン削除 | users_apitoken | DELETE | トークンレコード削除 |
| トークン認証 | users_apitoken | SELECT, UPDATE | トークン検証、last_seen更新 |

### テーブル別操作詳細

#### users_apitoken

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | user_id, key, name, expiry | 入力値 | keyはハッシュ化済み |
| UPDATE | name, expiry, active, revoked | 入力値 | |
| UPDATE | last_seen | 現在日時 | API認証成功時 |
| SELECT | key | トークン文字列で検索 | ハッシュ比較 |
| DELETE | pk | 削除対象ID | |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 401 | AuthenticationFailed | トークンが無効または期限切れ | 新しいトークンを取得 |
| 403 | PermissionDenied | 他ユーザーのトークンを操作 | 自身のトークンのみ操作 |
| 404 | NotFound | トークンが存在しない | トークンIDを確認 |
| 400 | ValidationError | 入力データが不正 | 入力値を修正 |

### リトライ仕様

特別なリトライ仕様は不要。トークン認証失敗は即座にエラーを返却。

## トランザクション仕様

- トークン作成・更新・削除は個別のトランザクションで処理
- API認証時のlast_seen更新は非同期で処理可能

## パフォーマンス要件

- トークン認証：50ms以内
- トークン作成：100ms以内
- トークンリスト取得：200ms以内

## セキュリティ考慮事項

- トークン文字列はSHA256でハッシュ化して保存
- 生成時以外はトークン文字列を復元不可
- HTTPSでの通信を前提
- トークンのスコープ制限（将来拡張予定）
- 定期的なトークンローテーション推奨

## 備考

ApiTokenモデルの属性:
- token_length: 64文字（設定可能）
- ハッシュアルゴリズム: SHA256
- トークン形式: `inv-{random_hex}`

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

APIトークンのモデル定義を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | models.py | `src/backend/InvenTree/users/models.py` | ApiTokenクラス（83-199行目）の構造 |

**読解のコツ**:
- **83-105行目**: クラス定義とフィールド宣言
- **107-125行目**: tokenプロパティでのハッシュ化処理
- **127-153行目**: generate_keyメソッドでトークン文字列生成
- **155-175行目**: 認証に使用されるメソッド

#### Step 2: エントリーポイントを理解する

REST APIエンドポイントを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | api.py | `src/backend/InvenTree/users/api.py` | ApiTokenList（281-302行目）とApiTokenDetail（304-330行目） |

**主要処理フロー**:
1. **281-302行目**: ApiTokenList.get_queryset()でユーザーのトークン一覧を取得
2. **304-330行目**: ApiTokenDetailで個別トークン操作
3. フィルタリングでuser=request.userを強制

#### Step 3: 認証処理を理解する

トークン認証の処理を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | authentication.py | `src/backend/InvenTree/users/authentication.py` | InvenTreeTokenAuthentication（実装を確認） |

**主要処理フロー**:
- HTTPヘッダーからトークン文字列を取得
- ApiToken.objects.filter()でトークン検索
- 有効性チェック（active, revoked, expiry）
- 認証成功時にlast_seenを更新

### プログラム呼び出し階層図

```
API リクエスト
    │
    ├─ Authorization: Token {token_string}
    │
    ▼
InvenTreeTokenAuthentication
    │
    ├─ authenticate()
    │      ├─ トークン文字列取得
    │      ├─ ApiToken検索
    │      └─ 有効性検証
    │
    └─ 認証成功
           ├─ request.user設定
           └─ last_seen更新

ApiTokenList / ApiTokenDetail
    │
    ├─ GET: トークン一覧/詳細取得
    │      └─ user=request.userでフィルタ
    │
    ├─ POST: トークン作成
    │      ├─ generate_key()
    │      └─ ハッシュ化して保存
    │
    ├─ PATCH: トークン更新
    │      └─ name, expiry, active, revoked
    │
    └─ DELETE: トークン削除
```

### データフロー図

```
[入力]                    [処理]                           [出力]

トークン作成要求 ───▶ generate_key() ───▶ トークン文字列
        │                  │                    │
        │                  ▼                    │
        │            ハッシュ化 ───▶ DB保存     │
        │                  │                    │
        │                  ▼                    ▼
        │         ApiToken(hashed)    トークン文字列（1回表示）

API認証 ───▶ Token解析 ───▶ ハッシュ比較 ───▶ 認証結果
        │                                        │
        │                                        ▼
        │                              last_seen更新
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| models.py | `src/backend/InvenTree/users/models.py` | ソース | ApiTokenモデル定義 |
| api.py | `src/backend/InvenTree/users/api.py` | ソース | トークンAPIエンドポイント |
| serializers.py | `src/backend/InvenTree/users/serializers.py` | ソース | トークンシリアライザ |
| authentication.py | `src/backend/InvenTree/users/authentication.py` | ソース | トークン認証バックエンド |
| SecurityContent.tsx | `src/frontend/src/pages/Index/Settings/UserSettings/SecurityContent.tsx` | フロントエンド | トークン管理UI |
