認証のテスト方法:Webアプリケーション向け完全ガイド

認証は、アプリケーションセキュリティにおける最も深刻な脆弱性が潜む領域であり、同時に自動テストのカバレッジが最も欠けがちな領域でもあります。認証フローの不備は、ユーザーに不便をかけるだけでなく、ユーザーデータの流出、アカウント乗っ取り、そして法規制上のリスクをもたらします。
AIコーディングツールを利用しているチームにとって、認証テストは特に重要です。AIコーディングエージェントが生成する認証フローは、正常系では正しく動作するものの、エッジケースを見落とすことが多くあります。たとえば、トークンの有効期限切れの処理、ログアウト時のセッション無効化、OAuthのstateパラメーターの検証、同時セッションの管理などが挙げられます。
本ガイドでは、認証テストで実際に必要なことと、それを体系的に実装する方法を解説します。
認証テストのカバー範囲
認証テストは、アプリケーションがユーザーを正しく識別し、セッションを通じてそのIDを維持できることを検証します。複数の層にまたがります:
機能的な認証:ログインは機能するか?ユーザーはログアウトできるか?パスワードリセットは正しく機能するか?
セッション管理:セッションは正しく確立・維持・終了されているか?セッショントークンは安全か?
セキュリティ:アプリケーションは認証攻撃に対して耐性があるか?認可チェックは適切に実施されているか?
エッジケース:トークンが期限切れになった場合はどうなるか?ユーザーが新しいデバイスからログインした場合は?セッションが競合した場合は?
認証テスト完全チェックリスト
ログインフロー
- 有効な認証情報でログインに成功し、セッションが確立される
- 無効な認証情報の場合、どのフィールドが誤っているかを明かさない適切なエラーが返される(「メールアドレスが見つかりません」ではなく「メールアドレスまたはパスワードが無効です」)
- 空の認証情報が適切に処理される
- 非常に長い入力値がサーバーエラーを引き起こさない
- 繰り返しのログイン失敗後にレート制限が適用される
- フォームベースのログインにCSRF対策が実装されている
セッション管理
- セッショントークンがHttpOnly Cookie(JavaScriptからアクセス不可)またはメモリ上(localStorageではなく)に設定されている
- 設定された非アクティブタイムアウト後にセッションが期限切れになる
- ログアウト時にセッションが無効化され、ログアウト後に古いトークンが再利用できない
- パスワード変更後にセッションが無効化される
- 同時セッションがポリシーに従って動作する(すべて許可、1つに制限、など)
パスワードリセット
- メールアドレスが存在する場合にリセットリンクが送信される(未認証ユーザーに対してメールアドレスの存在を明かさない)
- リセットトークンが適切な時間枠(通常1〜24時間)で期限切れになる
- リセットトークンが使い捨てであり、パスワード変更後に再利用できない
- 脆弱なパスワードがわかりやすいエラーメッセージとともに拒否される
OAuth / SSOフロー
- 認可リダイレクトにCSRFを防止するstateパラメーターが使用されている
- コールバック時にstateパラメーターが検証される
- コールバックハンドラーが認可コードを交換する前に検証を行う
- OAuth失敗時にサーバーエラーなく適切に処理される
- アカウントのリンク(OAuthと既存アカウントの連携)に確認が必要である
保護されたルートへのアクセス
- すべての保護されたルートが未認証リクエストに対して401を返す(またはログインページへリダイレクトする)
- すべての保護されたルートが十分な権限を持たない認証済みユーザーに対して403を返す
- 認証チェックがUIだけでなくサーバーサイドで実施される
- セッションクッキーのクリアによるクッキー操作で、正しく認証が解除されること
認証テストの自動化
TestSpriteで認証フローをテストする
TestSpriteのエージェント型テストエンジンは、要件から認証テストケースを自動生成します。PRDに認証フローの仕様が記載されている場合、以下のテストを生成します。
- 有効な認証情報でのログイン
- 無効な認証情報でのログイン(誤ったパスワード、存在しないメールアドレス、空フィールド)
- ログアウトおよびセッション無効化の検証
- 未認証状態でのプロテクトルートへのアクセス
- OAuthフローの完了および失敗時のハンドリング
エンジンはクラウドサンドボックス上の実際のアプリケーションに対してこれらのテストを実行し、分離されたテストユーザーを使用することで、テスト同士が干渉したり恒久的な状態が残ったりしないようにします。
Playwrightで認証をテストする
スクリプトベースのテストでは、Playwrightに認証状態管理機能が組み込まれています。
これにより一度だけ認証を行い、「authenticated」プロジェクト内のすべてのテストで認証状態を再利用できるため、テストごとにログインフローを繰り返す必要がなくなります。
APIレベルの認証テスト
APIレベルで認証をテストする場合:
AIが生成しやすい認証バグのテストパターン
AIコーディングエージェントが頻繁に誤るパターンを具体的に示します。
リソースエンドポイントでの認可の欠如。AIはCRUDエンドポイントを生成する際、認証は正しく要求するものの、認証済みユーザーがそのリソースの所有者であるかを検証しないケースがあります。/api/orders/:id はログインを要求しつつも、認証済みユーザーの注文だけでなく、IDで指定された任意の注文を返してしまう可能性があります。
セッションクッキーの設定ミス。AIが生成するセッション設定では、セッションクッキーにHttpOnly: trueおよびSecure: trueフラグが省略されることが多く、トークンがJavaScriptからアクセス可能になったり、HTTP経由で送信されたりするリスクがあります。
OAuthのstateパラメータの省略。AIが生成するOAuthフローでは、プロバイダーへのリダイレクトとコールバック処理は行うものの、stateパラメータの生成と検証が省略されることが多く、CSRFの脆弱性が生じます。
サーバーサイドを無効化しないログアウト。AIが生成するログアウト処理では、クライアントサイドのクッキーやlocalStorageをクリアするだけで、サーバーサイドのセッションを無効化しないことがよくあります。その結果、トークンは有効期限が切れるまで有効なままです。
これらはすべて、TestSpriteの認証テストカバレッジをアプリケーションに適用することで検出されます。
TestSpriteで認証テストを設定する →