Skip to content

認証設計 ​

JWT ベースのセッション認証とロールベースアクセス制御 (RBAC) の設計です。

認証フロー ​

mermaid
sequenceDiagram
    participant User as ユーザー
    participant Browser as ブラウザ
    participant MW as ミドルウェア
    participant Auth as 認証API
    participant DB as SQLite

    User->>Browser: ログインページ
    Browser->>Auth: POST /api/auth/login<br/>{email, password}
    Auth->>DB: ユーザー検索
    DB-->>Auth: User レコード
    Auth->>Auth: bcrypt.compare(password, hash)
    alt 認証成功
        Auth->>Auth: JWT 生成 (HS256)
        Auth-->>Browser: Set-Cookie: token=jwt (httpOnly, secure)
        Browser->>MW: 以降のリクエスト (Cookie 自動送信)
        MW->>MW: JWT 検証
        MW-->>Browser: 200 OK
    else 認証失敗
        Auth-->>Browser: 401 Unauthorized
    end

JWT トークン設計 ​

ペイロード ​

json
{
  "sub": "user_id",
  "email": "user@example.com",
  "role": "admin",
  "iat": 1700000000,
  "exp": 1700086400
}

設定 ​

項目値
アルゴリズムHS256
有効期限24時間
署名キーOS Keychain の JWT_SECRET
送信方法httpOnly Cookie
Set-Cookie: token=eyJhbGci...;
  HttpOnly;
  Secure;
  SameSite=Strict;
  Path=/;
  Max-Age=86400

ロールベースアクセス制御 ​

ロール定義 ​

ロール説明権限
admin管理者全操作 + ユーザー管理 + 設定変更
memberメンバーブックマーク閲覧 + 検索 + エクスポート
viewer閲覧者ブックマーク閲覧のみ

エンドポイント別アクセス権限 ​

mermaid
graph TD
    subgraph Public["認証不要"]
        Login["POST /api/auth/login"]
        Register["POST /api/auth/register\n(招待コード必須)"]
    end

    subgraph Viewer["viewer 以上"]
        GetBookmarks["GET /api/bookmarks"]
        GetStats["GET /api/stats"]
        GetMindmap["GET /api/mindmap"]
    end

    subgraph Member["member 以上"]
        Search["GET /api/search/ai"]
        Export["GET /api/export"]
        Categorize["POST /api/categorize"]
    end

    subgraph Admin["admin のみ"]
        Settings["*/api/settings/*"]
        Users["*/api/users/*"]
        Import["POST /api/import/*"]
    end
エンドポイントviewermemberadmin
GET /api/bookmarksooo
GET /api/statsooo
GET /api/mindmapooo
GET /api/search/ai-oo
GET /api/export-oo
POST /api/categorize-oo
POST /api/import/*--o
*/api/settings/*--o
*/api/users/*--o

招待コード方式 ​

新規ユーザーの登録は招待コード方式です。

mermaid
sequenceDiagram
    participant Admin as 管理者
    participant API as API
    participant NewUser as 新規ユーザー

    Admin->>API: POST /api/users/invite<br/>{role: "member"}
    API-->>Admin: {inviteCode: "abc123"}
    Admin->>NewUser: 招待コードを共有
    NewUser->>API: POST /api/auth/register<br/>{name, email, password, inviteCode: "abc123"}
    API->>API: 招待コード検証
    API->>API: パスワードハッシュ化 (bcrypt, rounds=12)
    API-->>NewUser: 201 Created + JWT Cookie

ミドルウェア実装 ​

mermaid
flowchart TD
    Request["リクエスト"] --> CheckPath{パスが\n公開エンドポイント?}
    CheckPath -->|Yes| Handler["APIハンドラー"]
    CheckPath -->|No| CheckToken{Cookie に\ntoken あり?}
    CheckToken -->|No| Reject401["401 Unauthorized"]
    CheckToken -->|Yes| Verify{JWT 検証}
    Verify -->|無効/期限切れ| Reject401
    Verify -->|有効| CheckRole{ロール\n権限チェック}
    CheckRole -->|権限あり| Handler
    CheckRole -->|権限なし| Reject403["403 Forbidden"]

セキュリティ対策 ​

パスワード ​

  • ハッシュ: bcrypt (cost factor: 12)
  • 比較: 定数時間比較 (crypto.timingSafeEqual)
  • ポリシー: 最低8文字(将来的に強化予定)

CSRF 対策 ​

  • SameSite=Strict Cookie 属性
  • カスタムヘッダー検証(API リクエスト)

レート制限 ​

エンドポイント制限
POST /api/auth/login5回/分
POST /api/auth/register3回/時
その他 API60回/分