Feature

認証フロー 12 Scenarios

Authentication Flow — UC-01 〜 UC-03

UC-01 ログイン AUTH-001 · AUTH-002 · AUTH-003

スタッフがメールアドレスとパスワードを使ってPOSシステムにログインする。 JWTアクセストークン(1時間)とリフレッシュトークン(30日)を発行し、ダッシュボードへリダイレクトする。

Background 各シナリオの共通前提
Given ログイン画面 /login が表示されている
Scenarios
01
Scenario · @happy-path
正常なログイン
Givenスタッフは有効なメールアドレスを入力している
And正しいパスワードを入力している
When「ログイン」ボタンをクリックする
ThenシステムはJWTアクセストークンとリフレッシュトークンを発行する
Andダッシュボード画面 /dashboard へリダイレクトされる
02
Scenario · @error
無効な認証情報でのログイン失敗
Givenスタッフは無効なメールアドレスまたはパスワードを入力している
When「ログイン」ボタンをクリックする
Then「メールアドレスまたはパスワードが正しくありません」エラーを表示する
Andログイン画面に留まる
03
Scenario · @security
ログイン回数制限(レートリミット)
Given同一IPアドレスから10回のログイン試行が行われている
Whenさらにログインを試みる
ThenHTTP 429 Too Many Requests を返す
And「ログイン試行回数が上限を超えました。しばらく待ってから再試行してください。」を表示する
# 制限: 1分間に10回まで(per-isolate, best-effort)
04
Scenario · @security
管理者ログイン(環境変数フォールバック)
GivenADMIN_EMAILADMIN_PASSWORD が環境変数に設定されている
When管理者メールアドレスとパスワードでログインする
Thenrole = "admin" のJWTが発行される
Andemployee_id = 0 として記録される
# タイミング攻撃防止のため timingSafeEqual() で比較する
UC-02 パスワードリセット AUTH-006 〜 AUTH-008

スタッフがパスワードを忘れた場合に、メールアドレス経由でリセットする。 ユーザー列挙攻撃を防ぐため、未登録アドレスでも同一レスポンスを返す。

Background 各シナリオの共通前提
Given スタッフはパスワードを忘れている
Scenarios
05
Scenario · @happy-path
パスワードリセットメールの送信
Givenスタッフはログイン画面の「パスワードを忘れた方はこちら」をクリックしている
When登録済みメールアドレスを入力して「送信」をクリックする
Then「パスワードリセットのご案内メールを送信しました」メッセージを表示する
Andリセット用URLを含むメールが送信される
06
Scenario · @happy-path
リセットリンクからのパスワード変更
Givenスタッフはリセットメールのリンクをクリックしている
When新しいパスワードを2回入力して「変更する」をクリックする
Thenパスワードハッシュが更新される
# PBKDF2-SHA256, 600,000 iterations
Andログイン画面へリダイレクトされる
07
Scenario · @security
未登録メールアドレスでのリセット要求
Givenスタッフは未登録のメールアドレスを入力している
When「送信」をクリックする
Then「パスワードリセットのご案内メールを送信しました」と同一メッセージを表示する
# User Enumeration Attack 防止のため実際には未送信
UC-03 ログアウト / トークン更新 AUTH-005 · NF-S003

スタッフが自分のセッションを安全に終了する。リフレッシュトークンはKVブラックリストに登録され以降の使用を無効化する。 他者のトークンを無効化するDoS攻撃も防ぐ。アクセストークン(1時間)失効時はリフレッシュトークン(30日)で自動更新する。

Background 各シナリオの共通前提
Given スタッフは認証済みでPOSシステムを利用中である
Scenarios
08
Scenario · @happy-path
正常なログアウト
Givenスタッフはサイドバーの「ログアウト」をクリックしている
When確認ダイアログで「OK」をクリックする
Thenリフレッシュトークンが REFRESH_TOKEN_KV ブラックリストに登録される
Andログイン画面 /login へリダイレクトされる
09
Scenario · @alternative
ログアウトのキャンセル
Givenスタッフはサイドバーの「ログアウト」をクリックしている
When確認ダイアログで「キャンセル」をクリックする
Thenログアウトせずに現在の画面に留まる
10
Scenario · @security
他者トークンの無効化試行を拒否
GivenスタッフAとスタッフBが認証済みである
AndスタッフAがスタッフBのリフレッシュトークンを入手している
WhenスタッフBのトークンでログアウトリクエストを送信する
ThenHTTP 403 Forbidden を返す
# payload.sub !== me.sub の検証でDoS攻撃を防ぐ
11
Scenario · @happy-path
アクセストークンの自動更新
Givenアクセストークン(pos_access)の有効期限が切れている
Andリフレッシュトークン(pos_refresh)は有効である
When保護されたAPIを呼び出して 401 が返る
Thenプロキシが POST /v1/auth/refresh を実行し新しいアクセストークンを発行する
And元のリクエストを 1 回だけ自動リトライする
# 自動リトライは1回まで — 再失敗時は /login へリダイレクト
12
Scenario · @security
失効済みリフレッシュトークンでの更新拒否
Givenログアウト済みでブラックリスト登録されたリフレッシュトークンを保持している
Whenそのトークンで POST /v1/auth/refresh を実行する
ThenHTTP 401 Unauthorized を返す
And新しいアクセストークンは発行されない
# REFRESH_TOKEN_KV の blacklist:{jti} を照合 / typ === "refresh" も検証

キーワード凡例 / Keyword Legend

Given事前条件 When操作 Then期待結果 And前のステップを継続 But例外・除外条件