# 機能設計書 33-認証・ログイン

## 概要

本ドキュメントは、InvenTreeシステムにおける認証・ログイン機能の設計を定義する。ユーザー認証（ログイン、ログアウト）および多要素認証（MFA）を提供する。

### 本機能の処理概要

認証・ログイン機能は、InvenTreeシステムへのアクセスを制御し、ユーザーの身元を確認する。Django allauthを基盤として、ローカル認証、SSO認証、MFA認証をサポートする。

**業務上の目的・背景**：在庫管理システムには機密情報（価格、取引先情報、在庫数等）が含まれるため、適切な認証によってアクセスを制限する必要がある。また、企業のセキュリティポリシーに対応するため、多要素認証やシングルサインオン機能を提供する。

**機能の利用シーン**：
- 従業員のシステム利用開始時のログイン
- 業務終了時のログアウト
- セキュリティ強化のためのMFA設定
- パスワード忘れ時のリセット処理
- 新規ユーザー登録（許可されている場合）
- SSOプロバイダー経由のログイン

**主要な処理内容**：
1. ユーザー名/パスワードによる基本認証
2. SSO（シングルサインオン）認証
3. 多要素認証（TOTP/静的トークン）
4. パスワード変更・リセット
5. メールアドレス確認
6. セッション管理
7. 新規ユーザー登録

**関連システム・外部連携**：
- Django allauth（認証フレームワーク）
- django-otp（多要素認証）
- OAuth2プロバイダー（Google, Microsoft等）
- LDAP認証サーバー
- メールサーバー（パスワードリセット、確認メール）

**権限による制御**：認証機能自体は全ユーザーがアクセス可能。MFA強制設定は管理者が設定可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | ログイン画面 | 主画面 | ユーザー名・パスワード入力、ログイン実行、SSOログイン |
| 2 | ログアウト画面 | 主画面 | ログアウト処理の実行 |
| 3 | 新規登録画面 | 主画面 | 新規ユーザー登録フォームの入力・送信処理 |
| 4 | MFA認証画面 | 主画面 | 二要素認証コードの入力・検証処理 |
| 5 | MFA設定画面 | 主画面 | 二要素認証の初期設定・有効化処理 |
| 6 | パスワード変更画面 | 主画面 | 現在のパスワード確認、新パスワード設定処理 |
| 7 | パスワードリセット要求画面 | 主画面 | メールアドレス入力、リセットメール送信要求処理 |
| 8 | パスワード再設定画面 | 主画面 | 新パスワードの設定・確認処理 |
| 9 | メール確認画面 | 主画面 | メールアドレス確認トークンの検証処理 |
| 36 | ユーザー設定画面 | 参照画面 | セキュリティ設定（MFA等） |

## 機能種別

認証・セキュリティ処理

## 入力仕様

### ログイン入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| login | str | Yes | ユーザー名またはメールアドレス | 空文字不可 |
| password | str | Yes | パスワード | 空文字不可 |

### MFA認証入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| code | str | Yes | TOTPコード | 6桁数字 |

### パスワード変更入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| oldpassword | str | Yes | 現在のパスワード | 正しいパスワードであること |
| password1 | str | Yes | 新しいパスワード | Django標準バリデーション |
| password2 | str | Yes | パスワード確認 | password1と一致すること |

### 入力データソース

- フロントエンド認証フォーム
- REST API経由のJSON入力
- SSOプロバイダーからのコールバック

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| token | str | 認証トークン（APIトークン取得時） |
| user | object | 認証されたユーザー情報 |
| session_key | str | セッションキー |

### 出力先

- セッションストア（Django session）
- ブラウザCookie
- REST APIレスポンス

## 処理フロー

### 処理シーケンス

```
1. ログインリクエスト受信
   └─ 認証情報（ユーザー名/パスワード）の取得
2. ユーザー認証
   └─ Djangoバックエンドによる認証
3. MFAチェック（有効な場合）
   └─ MFA認証画面へリダイレクト
4. MFA認証（有効な場合）
   └─ TOTPコードの検証
5. セッション作成
   └─ ログインセッションの生成
6. リダイレクト
   └─ ダッシュボードまたは元のページへ
```

### フローチャート

```mermaid
flowchart TD
    A[ログインリクエスト] --> B{認証方式}
    B -->|ローカル| C[ユーザー名/パスワード認証]
    B -->|SSO| D[SSOプロバイダーへリダイレクト]
    C --> E{認証成功?}
    D --> F[SSOコールバック]
    F --> E
    E -->|No| G[認証エラー]
    E -->|Yes| H{MFA有効?}
    H -->|Yes| I[MFA認証画面]
    H -->|No| J[セッション作成]
    I --> K{MFA認証成功?}
    K -->|Yes| J
    K -->|No| G
    J --> L[ダッシュボードへリダイレクト]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-33-01 | MFA強制 | LOGIN_ENFORCE_MFA設定時、全ユーザーにMFAを要求 | グローバル設定時 |
| BR-33-02 | 登録制限 | LOGIN_ENABLE_REG設定でユーザー登録の可否を制御 | 新規登録時 |
| BR-33-03 | SSO登録 | LOGIN_ENABLE_SSO_REG設定でSSO経由の登録を制御 | SSO認証時 |
| BR-33-04 | パスワードポリシー | Djangoのパスワードバリデーションを適用 | パスワード設定時 |
| BR-33-05 | MFA設定変更時セッション無効化 | MFA強制設定変更時に全セッションを終了 | 設定変更時 |

### 計算ロジック

TOTP認証:
- 30秒間隔のタイムベースワンタイムパスワード
- HMAC-SHA1アルゴリズム使用
- 6桁の数字コード

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| ログイン成功 | usersessions_usersession | INSERT | セッション作成 |
| ログアウト | usersessions_usersession | DELETE | セッション削除 |
| MFA設定 | mfa_authenticator | INSERT | MFA設定追加 |
| パスワード変更 | auth_user | UPDATE | パスワード更新 |
| メール確認 | account_emailaddress | UPDATE | verified=True |

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

#### usersessions_usersession

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | user_id, session_key, ip等 | ログインユーザー情報 | ログイン成功時 |
| DELETE | session_key | 削除対象セッション | ログアウト時 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| AUTH_FAILED | AuthenticationError | 認証情報が不正 | ユーザー名/パスワードを確認 |
| MFA_REQUIRED | MFARequired | MFA認証が必要 | MFAコードを入力 |
| MFA_INVALID | MFAInvalid | MFAコードが不正 | 正しいコードを入力 |
| ACCOUNT_INACTIVE | AccountInactive | アカウントが無効 | 管理者に連絡 |
| EMAIL_NOT_VERIFIED | EmailNotVerified | メール未確認 | 確認メールを再送信 |

### リトライ仕様

- 認証失敗時：即座にエラーを返却
- レートリミット：ブルートフォース対策として実装可能

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

- ログイン処理：セッション作成は個別トランザクション
- パスワード変更：User更新と関連処理を単一トランザクションで実行
- MFA設定：Authenticator作成は個別トランザクション

## パフォーマンス要件

- ログイン処理：2秒以内に完了
- MFA認証：1秒以内に完了
- セッション検証：100ms以内

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

- パスワードはPBKDF2_SHA256でハッシュ化
- セッションはHTTPOnly Cookieで管理
- CSRF保護を適用
- ブルートフォース対策（アカウントロックアウト機能を検討）
- MFA設定変更時の再認証要求
- セキュアなパスワードリセットトークン

## 備考

フロントエンド認証フロー（React）:
- Login.tsx: ログインフォーム
- Logout.tsx: ログアウト処理
- MFA.tsx: MFA認証
- MFASetup.tsx: MFA初期設定
- Register.tsx: 新規登録
- ChangePassword.tsx: パスワード変更
- Reset.tsx/ResetPassword.tsx: パスワードリセット

---

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

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

### 推奨読解順序

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

認証に関連するデータモデルを確認する。

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

**読解のコツ**: Django allauthおよびdjango-otpのモデルも使用されているが、それらはライブラリ内で定義されている。

#### Step 2: フロントエンド認証フローを理解する

React側の認証UIを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Login.tsx | `src/frontend/src/pages/Auth/Login.tsx` | ログインフォームと認証フロー |
| 2-2 | MFA.tsx | `src/frontend/src/pages/Auth/MFA.tsx` | MFA認証画面 |
| 2-3 | MFASetup.tsx | `src/frontend/src/pages/Auth/MFASetup.tsx` | MFA設定画面 |

**主要処理フロー**:
1. **Login.tsx 70-88行目**: useEffectでログイン状態チェック、URLパラメータからの自動ログイン
2. **Login.tsx 62-67行目**: ChangeHost()でホスト切り替え
3. **Login.tsx 23-42行目**: 状態管理とSSO設定の取得

#### Step 3: バックエンドAPIを理解する

認証関連のAPIエンドポイントを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | api.py | `src/backend/InvenTree/users/api.py` | GetAuthToken（346-412行目）でトークン取得 |
| 3-2 | authentication.py | `src/backend/InvenTree/users/authentication.py` | 認証バックエンドの実装 |

**主要処理フロー**:
- **346-412行目**: GetAuthToken.get()でAPIトークンを生成・取得
- トークンにはユーザー情報、作成日時、有効期限が含まれる

#### Step 4: 設定項目を理解する

認証に関連するシステム設定を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | system.py | `src/backend/InvenTree/common/setting/system.py` | LOGIN関連の設定項目 |

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

```
フロントエンド (Login.tsx)
    │
    ├─ doBasicLogin()
    │      └─ /api/auth/login/ POST
    │
    ├─ checkLoginState()
    │      └─ /api/user/me/ GET
    │
    └─ SSOログイン
           └─ /accounts/social/login/{provider}/

バックエンド (Django allauth)
    │
    ├─ LoginView
    │      └─ authenticate()
    │             └─ ModelBackend
    │
    └─ MFALoginView
           └─ TOTPDevice.verify_token()
```

### データフロー図

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

ログインフォーム ───▶ Django allauth ───▶ セッション作成
        │                  │                    │
        ▼                  ▼                    ▼
   認証情報        ユーザー認証           Cookieセット
        │                  │                    │
        │                  ▼                    │
        │            MFA認証(任意)              │
        │                  │                    │
        └──────────────────┴────────────────────┘
                           │
                           ▼
                    ダッシュボードへリダイレクト
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Login.tsx | `src/frontend/src/pages/Auth/Login.tsx` | フロントエンド | ログイン画面 |
| Logout.tsx | `src/frontend/src/pages/Auth/Logout.tsx` | フロントエンド | ログアウト処理 |
| MFA.tsx | `src/frontend/src/pages/Auth/MFA.tsx` | フロントエンド | MFA認証画面 |
| MFASetup.tsx | `src/frontend/src/pages/Auth/MFASetup.tsx` | フロントエンド | MFA設定画面 |
| Register.tsx | `src/frontend/src/pages/Auth/Register.tsx` | フロントエンド | 新規登録画面 |
| ChangePassword.tsx | `src/frontend/src/pages/Auth/ChangePassword.tsx` | フロントエンド | パスワード変更 |
| Reset.tsx | `src/frontend/src/pages/Auth/Reset.tsx` | フロントエンド | パスワードリセット要求 |
| ResetPassword.tsx | `src/frontend/src/pages/Auth/ResetPassword.tsx` | フロントエンド | パスワード再設定 |
| VerifyEmail.tsx | `src/frontend/src/pages/Auth/VerifyEmail.tsx` | フロントエンド | メール確認 |
| Layout.tsx | `src/frontend/src/pages/Auth/Layout.tsx` | フロントエンド | 認証画面レイアウト |
| LoggedIn.tsx | `src/frontend/src/pages/Auth/LoggedIn.tsx` | フロントエンド | ログイン後処理 |
| api.py | `src/backend/InvenTree/users/api.py` | バックエンド | ユーザーAPI |
| authentication.py | `src/backend/InvenTree/users/authentication.py` | バックエンド | 認証バックエンド |
| system.py | `src/backend/InvenTree/common/setting/system.py` | バックエンド | システム設定 |
