パスワードのリセット要求ページの変更
次に、パスワードのリセット要求ページから、パスワードのリセットメールを送信するように変更します。それには、パスワードのリセット要求ページのコメントアウトされたコードを利用します。まずはaspxファイルから見ていきましょう(リスト3)。
<%-- (1) パスワードリセット用情報入力欄 --%>
<asp:PlaceHolder ID="loginForm" runat="server">
<div class="form-horizontal">
<h4>パスワードを忘れた場合</h4>
<hr />
<asp:PlaceHolder runat="server" ID="ErrorMessage" Visible="false">
<p class="text-danger">
<asp:Literal runat="server" ID="FailureText" />
</p>
</asp:PlaceHolder>
<div class="form-group">
<asp:Label runat="server" AssociatedControlID="Email"
CssClass="col-md-2 control-label">電子メール</asp:Label>
<div class="col-md-10">
<asp:TextBox runat="server" ID="Email"
CssClass="form-control" TextMode="Email" />
<asp:RequiredFieldValidator runat="server" ControlToValidate="Email"
CssClass="text-danger" ErrorMessage="電子メール フィールドは必須です。" />
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<asp:Button runat="server" OnClick="Forgot" Text="送信"
CssClass="btn btn-default" />
</div>
</div>
</div>
</asp:PlaceHolder>
<%-- (2) パスワードリセットメール送信完了表示欄 --%>
<asp:PlaceHolder runat="server" ID="DisplayEmail" Visible="false">
<p class="text-info">
パスワードを再設定するには、メールをご確認ください。
</p>
</asp:PlaceHolder>
(1)パスワードリセット用情報入力欄
パスワードリセットを行うためのURLを含んだメールの送り先アドレスを入力します。
(2)パスワードリセットメール送信完了表示欄
メール送信後にその旨を表示する欄です。したがって、既定では非表示になっています。
次に分離コード側を見てみましょう(リスト4)。
protected void Forgot(object sender, EventArgs e)
{
if (IsValid)
{
// (1) ユーザーのメール アドレスを検証
var manager = Context.GetOwinContext().GetUserManager<ApplicationUserManager>();
ApplicationUser user = manager.FindByName(Email.Text);
if (user == null || !manager.IsEmailConfirmed(user.Id))
{
FailureText.Text = "ユーザーが存在しないか、未確認です。";
ErrorMessage.Visible = true;
return;
}
// アカウントの確認とパスワードの再設定を有効にする方法については、http://go.microsoft.com/fwlink/?LinkID=320771 を参照してください
// コードとパスワードの再設定ページへのリダイレクトを記載した電子メールを送信します
// (2) パスワードリセットトークン生成
string code = manager.GeneratePasswordResetToken(user.Id);
// (3) パスワードリセット用URL取得
string callbackUrl = IdentityHelper.GetResetPasswordRedirectUrl(code, Request);
// (4) パスワードリセットメール送信
manager.SendEmail(user.Id, "パスワードのリセット",
"<a href=\"" + callbackUrl + "\">こちら</a>をクリックして、"
+ "パスワードをリセットしてください.");
// (5) メール送信後画面表示
loginForm.Visible = false;
DisplayEmail.Visible = true;
}
}
(1)ユーザーのメール アドレスを検証
パスワードリセット用のURLを含んだメールの宛先として入力されたメールアドレスが、登録済みかどうか、またアカウントの確認も行われているかどうかを検証します。
(2)パスワードリセットトークン生成
UserManagerクラスのGeneratePasswordResetToken拡張メソッドを使い、登録したユーザーに対する「パスワードリセットトークン」を生成します。このパスワードトークンは、ユーザーID等から生成された英数字や記号が羅列された文字列です。
(3)パスワードリセット用URL取得
IdentityHelperクラスのGetResetPasswordRediretUrlメソッドを使い、(1)で生成したパスワードリセットトークンを埋め込んだ、パスワードリセットページのURLを生成します。
(4)パスワードリセットメール送信
(2)で取得したパスワードリセット用URLを埋め込んだ、パスワードリセットメールを送信します。
(5)メール送信後画面表示
メール送信を行ったことを表すため、「パスワードリセットメール送信完了表示欄」を表示し「パスワードリセット用情報入力欄」を非表示にします。
パスワードリセットページ
今度は送信したメールに添付したリンクから遷移する、パスワードリセットページを見てみましょう(リスト5)。aspxファイルは特に注意すべき点はないので説明を省きます。
protected void Reset_Click(object sender, EventArgs e)
{
// (1) パスワードリセットトークン取得
string code = IdentityHelper.GetCodeFromRequest(Request);
if (code != null)
{
var manager = Context.GetOwinContext().GetUserManager<ApplicationUserManager>();
// (2) ユーザー情報取得
var user = manager.FindByName(Email.Text);
if (user == null)
{
ErrorMessage.Text = "ユーザー名が見つかりません";
return;
}
// (3) パスワードリセット
var result = manager.ResetPassword(user.Id, code, Password.Text);
if (result.Succeeded)
{
Response.Redirect("~/Account/ResetPasswordConfirmation");
return;
}
ErrorMessage.Text = result.Errors.FirstOrDefault();
return;
}
ErrorMessage.Text = "エラーが発生しました";
}
(1)パスワードリセットトークン取得
メールのリンクに含めたURLからパスワードリセットトークンの値を取得します。
パスワードリセットトークンは、アカウントの確認と同様にクエリ文字列のcodeパラメータに設定されており、IdentityHelperクラスのGetCodeFromRequestメソッドを使って取得できます。
(2)ユーザー情報の取得
パスワードをリセットする対象ユーザー情報を、UserManager<TUser>クラスのFindByName拡張メソッドで取得します。
(3)パスワードリセット
UserManger<TUser>クラスのResetPassword拡張メソッドを呼び出し、パスワードをリセットします。パスワードリセットに成功すると、パスワードリセット確認画面(Account\ResetPasswordConfirmation.aspx)に遷移します。この画面は単純な画面で、テンプレートで生成されたままで使用しますので、説明は割愛します。
以上でパスワードのリセットを使用する準備ができました。
