---
title: "Cognitoのパスワードリセット実装：ForgotPasswordと管理者リセット・ロックアウト設計"
url: "https://www.issoh.co.jp/tech/details/18514/"
published: 2026-10-18
updated: 2026-10-18
categories: ["AWS"]
publisher: "株式会社一創"
---

# Cognitoのパスワードリセット実装：ForgotPasswordと管理者リセット・ロックアウト設計

Amazon Cognitoのパスワードリセットは、利用者が自分でコードを受け取って再設定する自己解決型と、管理者がAPIで再設定させる管理者リセットの2経路で組みます。この記事では、復旧先の設定、ForgotPasswordとConfirmForgotPasswordを使う再設定画面のSDKコード、AdminResetUserPasswordとAdminSetUserPasswordの使い分け、パスワードポリシーとロックアウトの仕様まで、2026年10月時点の公式ドキュメントに沿って手順を示します。最後に示すのは、会員サービスと業務システムでどちらの経路を主にするかを判断するための、利用者数や連絡先を踏まえた具体的な条件です。

## まとめ：Cognitoのパスワードリセットは復旧先の2経路化から設計する

結論から書くと、リセットの実装で最初に決めるのはAPIの呼び方ではなく、コードを届ける先です。Cognitoは検証済みのメールアドレスか電話番号にしかリセットコードを送らず、MFAに使っている宛先にも送りません。復旧先を「メール優先、使えなければSMS」の2経路にし、`email`と`phone_number`の検証状態を揃えておけば、問い合わせ窓口に回るリセットの大半は自己解決で済みます。

管理者側は、コードを送り直すならAdminResetUserPassword、窓口で本人確認して一時パスワードを渡すならAdminSetUserPasswordと使い分けます。ロックアウトはCognitoが自動で掛ける仕様で、閾値の設定項目は公式ドキュメントにありません。パスワードの有効期限機能も無いため、定期変更が要件なら外部に変更日時を記録する仕組みが必要です。

## Cognitoのパスワードリセットを構成する3つのAPIと前提条件を確認する

ユーザープールとアプリクライアントがまだ無い場合は、[Cognitoで認証基盤を実装する手順：ユーザープール構築からJWT検証まで](https://www.issoh.co.jp/tech/details/17445/)で土台を作ってから本稿に進んでください。リセットの設定は既存のプールにも後から追加できます。

### パスワードリセット用の3つのAPI：呼び出す主体・認可・処理結果の違い

[パスワードとアカウント復旧の公式ガイド](https://docs.aws.amazon.com/cognito/latest/developerguide/managing-users-passwords.html)は、リセットのAPIを次の3つに整理しています。

| API                    | 呼ぶ主体 | 認可       | 結果                       |
| ---------------------- | ---- | -------- | ------------------------ |
| ForgotPassword         | 利用者  | クライアントID | コードを送信                   |
| AdminResetUserPassword | 管理者  | IAM      | RESET\_REQUIREDにしてコードを送信 |
| AdminSetUserPassword   | 管理者  | IAM      | 一時か恒久のパスワードを直接設定         |

前の2つはどちらも、利用者がコードと新しいパスワードをConfirmForgotPasswordで送って完了します。マネージドログインの「パスワードをお忘れですか？」リンクも、内部ではForgotPasswordと同じ流れです。

### リセットコードの送信条件：検証済みメールアドレスか電話番号への限定

[ForgotPasswordのAPIリファレンス](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API%5FForgotPassword.html)によると、検証済みの電話番号もメールアドレスも無い利用者には`InvalidParameterException`が返ります。管理者がCSVで一括登録した利用者は検証済みフラグが立っていないことが多く、本番で初めて誰もリセットできないと分かる事故が起きやすい箇所です。管理者はコンソールの属性編集か`AdminUpdateUserAttributes`で`email_verified`を`true`にできます。

リセットコードの有効期間は1時間です。アプリクライアントにクライアントシークレットがある場合、`SECRET_HASH`を付けないと`NotAuthorizedException`になります。ブラウザから直接呼ぶ構成なら、シークレット無しのクライアントを使います。

## アカウント復旧の送信先をAccountRecoverySettingで設定する手順

コードの送信先は、ユーザープールの`AccountRecoverySetting`で優先順位を決めます。何も設定しないと、検証済みの電話番号が優先され、電話番号が無い場合にメールへ送る旧来の挙動になります。SMSの費用をかけたくない場合に必要なのは、メールを明示的に1番にする設定です。

### AWS CLIのupdate-user-poolでメール優先・SMS予備の順位を設定する

メールを1番、SMSを2番にする設定です。オプション名は[update-user-poolのCLIリファレンス](https://docs.aws.amazon.com/cli/latest/reference/cognito-idp/update-user-pool.html)で確認できます。

```
# 現在の設定を退避してから変更する（update-user-poolは未指定の項目を既定値に戻す）
aws cognito-idp describe-user-pool \
  --user-pool-id ap-northeast-1_EXAMPLE > userpool-backup.json

aws cognito-idp update-user-pool \
  --user-pool-id ap-northeast-1_EXAMPLE \
  --account-recovery-setting 'RecoveryMechanisms=[{Name=verified_email,Priority=1},{Name=verified_phone_number,Priority=2}]'
```

注意点は、このコマンドが指定しなかった属性を既定値に戻すことです。上の例をそのまま本番で実行すると、メッセージテンプレートやLambdaトリガーなど既存の設定が消えるおそれがあります。退避したJSONの値をすべて渡すか、CloudFormationやTerraformなどのIaCで復旧設定を管理する方が安全です。セルフサービスを止めて管理者だけが再設定する運用なら、`Name=admin_only`を単独で指定します。

### MFAとパスワードリセットの送信先が衝突する条件と2経路化による回避策

Cognitoは、MFAとリセットのコードを同じメールアドレスや電話番号に送りません。メールMFAを優先方式にした利用者はメールでリセットコードを受け取れず、SMS MFAの利用者はSMSで受け取れません。復旧先がメールしか無い構成でメールMFAを有効にすると、パスワードを忘れた利用者は自己解決できなくなります。

公式ガイドの対策は、`email`と`phone_number`を両方必須にするか、復旧先を2経路にすることです。両方を持つ利用者には、CognitoがMFAに使っていない側へ自動でコードを送ります。MFA方式の選び方は[Cognito MFAの設定手順：TOTP・SMS・メールの有効化と必須化の判断](https://www.issoh.co.jp/tech/details/18510/)で扱っており、TOTPを主にすればこの衝突自体が起きません。

## パスワード再設定画面の自作：SDKによるコード送信と新しいパスワードの確定

マネージドログインを使うなら、再設定画面はCognitoが用意します。ここで扱うのは、自作の画面からAWS SDK for JavaScript v3で呼ぶ場合の実装です。画面の見た目を調整したいだけなら[AWS Cognito Hosted UI（マネージドログイン）のカスタマイズ・日本語化と実装手順](https://www.issoh.co.jp/tech/details/3441/)の方が手数は少なく済みます。

### ForgotPasswordCommandでリセットコードを送信する

```
import {
  CognitoIdentityProviderClient,
  ForgotPasswordCommand,
  ConfirmForgotPasswordCommand,
} from "@aws-sdk/client-cognito-identity-provider";

const client = new CognitoIdentityProviderClient({ region: "ap-northeast-1" });
const CLIENT_ID = "1example23456789"; // シークレット無しのアプリクライアント

// 手順1：ユーザー名（メールアドレスのエイリアスも可）でコードを送らせる
export async function requestReset(username) {
  const res = await client.send(
    new ForgotPasswordCommand({ ClientId: CLIENT_ID, Username: username })
  );
  // 例：{ DeliveryMedium: "EMAIL", Destination: "j***@e***" }
  return res.CodeDeliveryDetails;
}
```

戻り値の`CodeDeliveryDetails`には、マスクされた送信先が入ります。画面には「j\*\*\*@e\*\*\* に確認コードを送りました」のようにそのまま表示できます。

### ConfirmForgotPasswordで新しいパスワードを確定し例外を文言に変える

```
// 手順2：コードと新しいパスワードで再設定を確定する
export async function confirmReset(username, code, newPassword) {
  try {
    await client.send(
      new ConfirmForgotPasswordCommand({
        ClientId: CLIENT_ID,
        Username: username,
        ConfirmationCode: code,
        Password: newPassword,
      })
    );
    return { ok: true };
  } catch (e) {
    const messages = {
      CodeMismatchException: "確認コードが正しくありません。",
      ExpiredCodeException: "確認コードの期限が切れています。もう一度送信してください。",
      InvalidPasswordException: "パスワードの条件を満たしていません。",
      PasswordHistoryPolicyViolationException: "過去に使ったパスワードは設定できません。",
      LimitExceededException: "試行回数の上限に達しました。時間をおいて再度お試しください。",
      TooManyFailedAttemptsException: "試行回数の上限に達しました。時間をおいて再度お試しください。",
    };
    return { ok: false, message: messages[e.name] ?? "再設定に失敗しました。" };
  }
}
```

例外名は[ConfirmForgotPasswordのAPIリファレンス](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API%5FConfirmForgotPassword.html)の一覧に合わせています。`InvalidPasswordException`のメッセージにはポリシー違反の理由が英語で入るため、画面には文字数や文字種の条件を日本語で併記しておくと問い合わせが減ります。

### PreventUserExistenceErrorsで利用者の存在を推測させない

リセット画面は、メールアドレスを入れて応答の違いを見れば登録の有無が分かる、という列挙攻撃の入口になります。[ユーザー存在エラーの公式ガイド](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pool-managing-errors.html)によると、アプリクライアントの`PreventUserExistenceErrors`を`ENABLED`にすると、存在しない利用者へのForgotPasswordにも模擬の`CodeDeliveryDetails`が返り、ConfirmForgotPasswordは`CodeMismatchException`を返します。

コンソールで作ったクライアントは既定で`ENABLED`ですが、APIやIaCで作った場合の既定は`LEGACY`（無効）です。`UserNotFoundException`を拾って「登録がありません」と表示する実装は、この設定と合わせて見直してください。

## 管理者によるパスワード再設定：コード送信と一時パスワード発行の手順

窓口に「ログインできない」と連絡が来たときに管理者が使う2つのAPIです。どちらもIAMで認可するため、呼び出すのは管理画面のバックエンドや運用担当のCLIに限ります。

### AdminResetUserPasswordによる再設定要求とコード送信

```
# 現在のパスワードを無効化し、利用者にリセットコードを送る
aws cognito-idp admin-reset-user-password \
  --user-pool-id ap-northeast-1_EXAMPLE \
  --username taro@example.com
```

[AdminResetUserPasswordのAPIリファレンス](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API%5FAdminResetUserPassword.html)によると、実行後の利用者は`RESET_REQUIRED`状態になり、サインインすると`PasswordResetRequiredException`が返ります。アプリはこの例外を受けたら前章の確定画面へ誘導します。このAPIはセルフサービスの復旧設定が有効なプールでしか使えないため、`admin_only`の運用では使えません。漏洩の疑いがあるアカウントを強制的に変更させる用途にも向いています。

### AdminSetUserPasswordで一時パスワードを発行するときの期限管理

```
# 一時パスワードを設定し、次回サインインで変更させる
aws cognito-idp admin-set-user-password \
  --user-pool-id ap-northeast-1_EXAMPLE \
  --username taro@example.com \
  --password 'Temp#2026-Example' \
  --no-permanent
```

[AdminSetUserPasswordのAPIリファレンス](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API%5FAdminSetUserPassword.html)のとおり、一時パスワードにすると状態は`FORCE_CHANGE_PASSWORD`になり、次回のサインインで`NEW_PASSWORD_REQUIRED`チャレンジが返ります。一時パスワードの有効期限はパスワードポリシーの`TemporaryPasswordValidityDays`で決まり、既定は7日です。期限内にサインインしなかった利用者は、管理者が再度設定する必要があります。

`--permanent`を付けると即座にそのパスワードでサインインできますが、管理者がパスワードを知っている状態が残るため、業務システムでは一時パスワードを原則にします。SAML連携などのフェデレーション利用者にパスワードを設定すると状態が`EXTERNAL_PROVIDER`から`CONFIRMED`に変わり、ローカルでもサインインできてしまいます。IdP経由の利用者のリセットはIdP側で行う運用にしてください。連携の構成は[Cognito SAML連携の手順：Entra IDでSSOを組む設定と属性マッピング](https://www.issoh.co.jp/tech/details/18512/)で解説しています。

## パスワードポリシーとロックアウトの仕様をリセット設計に反映する

リセットの回数を減らすにも、リセット経路を悪用させないにも、ポリシーとロックアウトの仕様を知っておく必要があります。

### 最小文字数・文字種・履歴24件までのパスワードポリシーを設定する

[PasswordPolicyType](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API%5FPasswordPolicyType.html)で設定できる値は次のとおりです。

| 項目                  | 範囲         | 補足              |
| ------------------- | ---------- | --------------- |
| MinimumLength       | 6〜99       | 入力できる長さは256字まで  |
| Require系4項目         | true／false | 大文字・小文字・数字・記号   |
| PasswordHistorySize | 0〜24       | Essentials以上で有効 |
| 一時パスワードの有効日数        | 0〜365      | 既定7日            |

履歴を設定すると、リセット時に過去と同じパスワードを指定した利用者へ`PasswordHistoryPolicyViolationException`が返ります。既存ユーザーをパスワードハッシュごと取り込んだ場合、取り込み時点ではポリシーが適用されない点も覚えておいてください。文字種の強制より長さを重視する考え方など、ポリシー値そのものの決め方は[パスワード管理のベストプラクティス：NIST SP 800-63B-4の要件と総務省・NISCの推奨、企業ポリシーの決め方](https://www.issoh.co.jp/column/details/13508/)にまとめています。

### サインイン5回失敗から始まる指数ロックアウトと解除される2つの条件

[認証の注意点をまとめた公式ガイド](https://docs.aws.amazon.com/cognito/latest/developerguide/authentication-flow-things-to-know.html)によると、パスワードでのサインインに5回失敗すると1秒のロックアウトが始まり、以後1回失敗するごとに時間が倍になって、最大で約15分に達します。累計の失敗回数をnとすると、ロック時間は2のn−5乗秒です。ロック中の試行は「Password attempts exceeded」の例外になり、次のロック時間には数えられません。

カウントが初期状態に戻る条件は、ロックが明けた後にサインインに成功するか、ロック後に15分間連続で試行しないかの2つです。公式ドキュメントにはこの閾値を変える設定は記載されておらず、挙動は変更されうると明記されています。特定の利用者を止めたい場合は、ロックではなく`AdminDisableUser`で無効化するのが管理側の手段になります。サインイン失敗やロックアウトをログで監査する方法は[Cognitoのログ取得手順：CloudTrailとユーザーアクティビティログでサインインを監査する](https://www.issoh.co.jp/tech/details/18518/)で解説しています。

### パスワードリセット要求の回数制限と漏洩パスワード検査の対象範囲

リセットそのものにも回数制限があり、1時間あたり5〜20回の範囲でリスクに応じて上限が決まります。上限に達すると`LimitExceededException`になるため、画面では時間をおいて再試行するよう案内します。

Plusプランの脅威保護を使うと、[漏洩した認証情報の検査](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pool-settings-compromised-credentials.html)をConfirmForgotPasswordで設定される新しいパスワードにも掛けられます。ただしAdminSetUserPasswordで管理者が設定したパスワードは検査の対象外です。

## Cognitoのパスワードリセット経路を判断する条件と見送るべき場面

ここまでの仕様を踏まえ、どの経路を主にするかを言い切ります。Cognitoの機能と料金の全体像は[Amazon Cognito（コグニート）とは？料金・できること・使い方をCLIとコード例で解説](https://www.issoh.co.jp/tech/details/3108/)で確認できます。

### 会員サービスは自己解決の2経路、業務システムは一時パスワード運用

一般消費者向けの会員サービスでは、ForgotPasswordによる自己解決を主にし、復旧先はメール優先・SMS予備の2経路にします。`PreventUserExistenceErrors`は必ず有効にし、エラー文言で登録の有無を漏らさないようにします。窓口の負荷を下げる効果が大きいのはこちらです。

利用者が数百人規模の業務システムで、メールアドレスが社内のものに限られるなら、`admin_only`にして管理者が一時パスワードを発行する運用でも回ります。退職者のアドレスにリセットコードが届く事態を避けられる点も利点です。ただし休日や夜間に利用者が自力で戻れなくなるため、窓口の対応時間を業務時間と合わせて決めておきます。

### パスワード定期変更が必須の要件と外部IdPへ委ねるべきケース

Cognitoのローカルユーザーのパスワードは自動では失効しません。社内規程で90日ごとの変更が求められている場合、変更日時を外部のデータストアに記録し、Lambdaトリガーで期限切れを判定して変更を促す仕組みを自分で作ることになります。この作り込みを避けたいなら、パスワードそのものを減らすパスワードレス認証への移行も選択肢です。方式の比較は[パスワードレス認証とは？方式4分類の実装難度と移行判断を実装者向けに解説](https://www.issoh.co.jp/tech/details/16411/)を参照してください。Cognito標準のパスキーで置き換える場合の設定とSDKコードは[Cognitoのパスキー実装手順：WebAuthnサインインの有効化とSDKでの登録・認証](https://www.issoh.co.jp/tech/details/18516/)にまとめています。

社員のIDをEntra IDやGoogle Workspaceで既に管理しているなら、Cognitoでリセット経路を作り込まず、IdPのセルフサービスリセットに委ねる方が二重管理を避けられます。復旧設計や既存IdPとの統合を含めて認証基盤を見直したい場合は、[認証基盤・ID管理システム開発](https://www.issoh.co.jp/service/system/identity/)でご相談いただけます。

## よくある質問

Cognitoのパスワードリセットとポリシー設定で、実装前によく確認される点をまとめました。

### リセットコードのメール本文を日本語に変えられますか？

確認メールの件名と本文は、コンソールの設定やLambdaトリガーによって日本語に変更可能です。コンソールのメッセージテンプレートで確認メールの件名と本文を編集するか、[カスタムメッセージのLambdaトリガー](https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-custom-message.html)で`triggerSource`が`CustomMessage_ForgotPassword`のときに本文を組み立てます。どちらの方法でも、コードを差し込む位置には`{####}`を入れる必要があります。

### ロックアウトされた利用者を管理者が解除できますか？

公式ドキュメントに記載されている解除条件は、ロック明けのサインイン成功と、15分間試行しないことの2つだけです。管理者が解除するAPIや閾値を変える設定は案内されていません。最大でも約15分で試行できる状態に戻るため、窓口では時間をおいて再試行するよう案内するのが現実的です。

### ForgotPasswordを呼んでもコードが届かないのはなぜですか？

原因は主に3つです。1つ目は、メールアドレスや電話番号が未検証であること。2つ目は、復旧先の宛先がMFAの宛先と重なっていること。3つ目は、SMSがサンドボックスのままで検証済みの番号にしか送れないことです。`PreventUserExistenceErrors`が有効だと、存在しない利用者にも成功に見える応答が返るため、入力したユーザー名自体の誤りも疑ってください。

### パスワードの有効期限を設定できますか？

Cognitoのパスワードポリシーに有効期限の項目はありません。設定できる期限は、管理者が発行する一時パスワードの`TemporaryPasswordValidityDays`だけです。定期変更が必要な場合は、変更日時を外部に記録し、期限を過ぎた利用者にAdminResetUserPasswordを実行するなどの仕組みを自分で用意します。

### Amplifyを使う場合も同じAPIが呼ばれますか？

Amplifyのライブラリが提供するパスワードリセットの関数は、内部でCognitoのForgotPasswordとConfirmForgotPasswordを呼んでいます。そのため、復旧先の設定、宛先の衝突、回数制限、ユーザー存在エラーの扱いは本稿の内容がそのまま当てはまります。関数名や引数はAmplifyのバージョンで変わるため、利用中の版のドキュメントで確認してください。

## 関連記事

- [Cognitoで認証基盤を実装する手順：ユーザープール構築からJWT検証まで](https://www.issoh.co.jp/tech/details/17445/)：リセット設定の前提になるユーザープールとトークン検証の全体像。
- [Cognito MFAの設定手順：TOTP・SMS・メールの有効化と必須化の判断](https://www.issoh.co.jp/tech/details/18510/)：リセット宛先と衝突しないMFA方式の選び方。
- [AWS Cognito Hosted UI（マネージドログイン）のカスタマイズ・日本語化と実装手順](https://www.issoh.co.jp/tech/details/3441/)：再設定画面を含むマネージドログインの調整方法。
- [パスワード管理のベストプラクティス：NIST SP 800-63B-4の要件と総務省・NISCの推奨、企業ポリシーの決め方](https://www.issoh.co.jp/column/details/13508/)：パスワードポリシーの値の決め方。
- [パスワードレス認証とは？方式4分類の実装難度と移行判断を実装者向けに解説](https://www.issoh.co.jp/tech/details/16411/)：リセットの負担そのものを減らす移行の判断。

---

出典: [Cognitoのパスワードリセット実装：ForgotPasswordと管理者リセット・ロックアウト設計](<https://www.issoh.co.jp/tech/details/18514/>)（株式会社一創）
