Skip to content

認証フロー設計

1. 概要

本プラットフォームの認証は GitLab OAuth 2.0 によるシングルサインオン(SSO)を採用する。認証後は JWT(JSON Web Token) によるステートレスなセッション管理を行う。

認証方式の選定理由

  • GitLab(gitlab.ethan-tech.jp)を開発基盤として使用するため、GitLab アカウントとの統合が必須
  • OAuth 2.0 Authorization Code Flow を採用し、セキュリティを担保
  • JWT により API サーバーのスケーラビリティを確保

2. GitLab OAuth 認証フロー

2.1 シーケンス図

┌──────────┐     ┌──────────────┐     ┌───────────────┐     ┌─────────────────────┐
│ ブラウザ  │     │ フロントエンド │     │ バックエンド    │     │ GitLab OAuth Server │
│          │     │ (SPA)        │     │ (API)          │     │ gitlab.ethan-tech.jp│
└────┬─────┘     └──────┬───────┘     └───────┬────────┘     └──────────┬──────────┘
     │                  │                     │                         │
     │  1. ログインボタン押下                   │                         │
     │─────────────────>│                     │                         │
     │                  │                     │                         │
     │                  │  2. GET /auth/gitlab │                         │
     │                  │─────────────────────>│                         │
     │                  │                     │                         │
     │                  │  3. リダイレクトURL返却│                         │
     │                  │<─────────────────────│                         │
     │                  │                     │                         │
     │  4. GitLab 認証画面へリダイレクト        │                         │
     │<─────────────────│                     │                         │
     │                  │                     │                         │
     │  5. GitLab ログイン・認可同意             │                         │
     │──────────────────────────────────────────────────────────────────>│
     │                  │                     │                         │
     │  6. コールバック (authorization_code)    │                         │
     │<─────────────────────────────────────────────────────────────────│
     │                  │                     │                         │
     │  7. コールバックURL転送                  │                         │
     │─────────────────>│                     │                         │
     │                  │                     │                         │
     │                  │  8. POST /auth/callback (code)                │
     │                  │─────────────────────>│                         │
     │                  │                     │                         │
     │                  │                     │  9. POST /oauth/token    │
     │                  │                     │  (code → access_token)   │
     │                  │                     │─────────────────────────>│
     │                  │                     │                         │
     │                  │                     │  10. access_token 返却   │
     │                  │                     │<─────────────────────────│
     │                  │                     │                         │
     │                  │                     │  11. GET /api/v4/user    │
     │                  │                     │  (GitLabユーザー情報取得) │
     │                  │                     │─────────────────────────>│
     │                  │                     │                         │
     │                  │                     │  12. ユーザー情報返却     │
     │                  │                     │<─────────────────────────│
     │                  │                     │                         │
     │                  │                     │  13. ユーザー作成/更新    │
     │                  │                     │  + JWT 発行              │
     │                  │                     │                         │
     │                  │  14. JWT トークン返却 │                         │
     │                  │<─────────────────────│                         │
     │                  │                     │                         │
     │  15. ログイン完了 │                     │                         │
     │<─────────────────│                     │                         │

2.2 OAuth アプリケーション設定

GitLab 側に OAuth Application を登録する。

項目
NameIssue Outsource Platform
Redirect URIhttps://<app-domain>/auth/callback
Scopesread_user, read_api, openid, profile, email
ConfidentialYes

2.3 取得する GitLab ユーザー情報

json
{
  "id": 1,
  "username": "example_user",
  "name": "Example User",
  "email": "user@example.com",
  "avatar_url": "https://gitlab.ethan-tech.jp/uploads/-/system/user/avatar/1/avatar.png",
  "web_url": "https://gitlab.ethan-tech.jp/example_user"
}

3. JWT トークン設計

3.1 トークン構成

項目説明
Access TokenAPI アクセス用。短寿命。
Refresh TokenAccess Token 更新用。長寿命。

3.2 Access Token ペイロード

json
{
  "sub": "user_uuid",
  "gitlab_id": 1,
  "username": "example_user",
  "role": "engineer",
  "iat": 1711600000,
  "exp": 1711603600
}
フィールド説明
substring (UUID)プラットフォーム内部のユーザー ID
gitlab_idintegerGitLab ユーザー ID
usernamestringGitLab ユーザー名
rolestringロール(manager, reviewer, engineer
iatinteger発行日時(Unix timestamp)
expinteger有効期限(Unix timestamp)

3.3 トークンライフサイクル

トークン有効期限保存場所
Access Token1 時間メモリ(JavaScript 変数)
Refresh Token7 日間HttpOnly Secure Cookie

3.4 トークンリフレッシュフロー

┌──────────┐     ┌──────────────┐     ┌───────────────┐
│ ブラウザ  │     │ フロントエンド │     │ バックエンド    │
└────┬─────┘     └──────┬───────┘     └───────┬────────┘
     │                  │                     │
     │  1. API リクエスト(期限切れ Access Token)│
     │─────────────────>│                     │
     │                  │─────────────────────>│
     │                  │  2. 401 Unauthorized │
     │                  │<─────────────────────│
     │                  │                     │
     │                  │  3. POST /auth/refresh│
     │                  │  (Refresh Token Cookie)│
     │                  │─────────────────────>│
     │                  │                     │
     │                  │  4. 新 Access Token   │
     │                  │  + 新 Refresh Token   │
     │                  │<─────────────────────│
     │                  │                     │
     │                  │  5. 元の API リクエスト再送│
     │                  │─────────────────────>│
     │                  │                     │
     │                  │  6. 正常レスポンス    │
     │                  │<─────────────────────│
     │                  │                     │
     │  7. 画面更新      │                     │
     │<─────────────────│                     │

3.5 Refresh Token のローテーション

  • Refresh Token は使用するたびに新しいトークンを発行(ローテーション)
  • 使用済み Refresh Token は無効化し、再利用を検知した場合は全トークンを無効化(トークン盗用対策)

4. セッション管理

4.1 セッション設計方針

  • ステートレス: JWT ベースでサーバー側にセッションストアを持たない(基本方針)
  • トークン無効化: Refresh Token のブラックリストを Redis で管理

4.2 セッション無効化(ログアウト)

  1. フロントエンドがメモリ上の Access Token を破棄
  2. バックエンドに POST /auth/logout を送信
  3. バックエンドが Refresh Token を Redis ブラックリストに追加
  4. Refresh Token Cookie を削除

4.3 強制セッション終了

以下のケースでは管理者が強制的にセッションを無効化する。

  • ユーザーのロール変更時
  • セキュリティインシデント発生時
  • ユーザーアカウントの無効化時

実装: 該当ユーザーの全 Refresh Token を Redis ブラックリストに追加する。

Set-Cookie: refresh_token=<token>;
  HttpOnly;
  Secure;
  SameSite=Strict;
  Path=/auth/refresh;
  Max-Age=604800

5. ロール付与フロー

本プラットフォームは 招待制 を採用し、自由登録は許可しない。

5.1 招待〜ロール付与シーケンス

┌──────────────┐     ┌───────────────┐     ┌─────────────────────┐     ┌─────────────┐
│ PM/マネージャー│     │ バックエンド    │     │ GitLab OAuth Server │     │ 招待された    │
│              │     │ (API)          │     │                     │     │ ユーザー     │
└──────┬───────┘     └───────┬────────┘     └──────────┬──────────┘     └──────┬──────┘
       │                     │                         │                       │
       │  1. ユーザー招待     │                         │                       │
       │  (email, role)      │                         │                       │
       │─────────────────────>│                         │                       │
       │                     │                         │                       │
       │                     │  2. 招待レコード作成     │                       │
       │                     │  + 招待メール送信        │                       │
       │                     │─────────────────────────────────────────────────>│
       │                     │                         │                       │
       │  3. 招待完了         │                         │                       │
       │<─────────────────────│                         │                       │
       │                     │                         │                       │
       │                     │                         │    4. 招待リンク       │
       │                     │                         │    クリック            │
       │                     │<────────────────────────────────────────────────│
       │                     │                         │                       │
       │                     │  5. GitLab OAuth フロー開始                      │
       │                     │─────────────────────────>│                       │
       │                     │                         │                       │
       │                     │                         │  6. GitLab ログイン    │
       │                     │                         │<──────────────────────│
       │                     │                         │                       │
       │                     │  7. OAuth コールバック    │                       │
       │                     │<─────────────────────────│                       │
       │                     │                         │                       │
       │                     │  8. ユーザー作成         │                       │
       │                     │  (招待のロールを付与)     │                       │
       │                     │                         │                       │
       │                     │  9. 初回ログインフラグ設定 │                      │
       │                     │─────────────────────────────────────────────────>│
       │                     │                         │                       │
       │                     │                         │  10. プロフィール      │
       │                     │                         │  設定画面へ            │
       │                     │                         │──────────────────────>│

5.2 招待の有効期限と制約

項目
招待リンク有効期限7 日間
再招待期限切れ後に PM が再招待可能
招待キャンセルPM が招待済み・未登録のユーザーをキャンセル可能
同一メールアドレス重複招待不可(既存ユーザーの場合はエラー)

6. 初回ログイン時のプロフィール設定フロー

6.1 フロー

┌──────────┐     ┌──────────────┐     ┌───────────────┐
│ ブラウザ  │     │ フロントエンド │     │ バックエンド    │
└────┬─────┘     └──────┬───────┘     └───────┬────────┘
     │                  │                     │
     │  1. 初回ログイン後 │                     │
     │  (is_profile_complete = false)          │
     │─────────────────>│                     │
     │                  │                     │
     │  2. プロフィール設定画面表示              │
     │<─────────────────│                     │
     │                  │                     │
     │  3. プロフィール入力・送信               │
     │─────────────────>│                     │
     │                  │  4. PUT /users/me/profile│
     │                  │─────────────────────>│
     │                  │                     │
     │                  │  5. バリデーション    │
     │                  │  + プロフィール保存   │
     │                  │  + is_profile_complete = true│
     │                  │                     │
     │                  │  6. 更新完了          │
     │                  │<─────────────────────│
     │                  │                     │
     │  7. メイン画面へ遷移│                    │
     │<─────────────────│                     │

6.2 必須プロフィール項目

項目必須説明
表示名Oプラットフォーム上の表示名(GitLab 名で初期値設定)
メールアドレスO連絡用(GitLab のメールで初期値設定)
スキルタグエンジニアのみ必須。対応可能な技術領域
銀行口座情報エンジニアのみ必須。報酬振込先
自己紹介-任意

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

7.1 CSRF 対策

  • SameSite=Strict Cookie による CSRF 防止
  • state パラメータによる OAuth CSRF 防止

7.2 XSS 対策

  • Access Token はメモリ保持(localStorage 不使用)
  • Refresh Token は HttpOnly Cookie(JavaScript からアクセス不可)

7.3 レート制限

エンドポイント制限
POST /auth/gitlab10 回/分/IP
POST /auth/refresh30 回/時/ユーザー
POST /auth/logout10 回/分/ユーザー

7.4 監査ログ

以下のイベントを監査ログに記録する。

  • ログイン成功/失敗
  • ログアウト
  • ロール変更
  • 招待の作成/キャンセル
  • トークンリフレッシュ
  • 強制セッション終了