喜帳面の日記

50歳越えおやじのASP.NET MVC への挑戦日記です。

Visual Studio Express 2012 for Web でいってみる 19.ログイン認証あたり3 パスワードのリセット

 

今回はログインパスワードのリセットにチャレンジしてみました。
初心者が行き当たりばったりにいろいろ動かしてみたときのメモなので、記載内容には勝手な解釈や誤りもあるかと思います。お気づきの点がありましたら、ご指摘よろしくお願いします。
 
さて、以前の記事、
Visual Studio Express 2012 for Web でいってみる 4.ログイン認証あたり2
このページで、MVC4の標準テンプレートで作成したプロジェクトのユーザープロファイルに[メールアドレス]を追加したときのメモ書きを残しました。
このとき、「ログインパスワードを忘れてしまったらどうする?」って疑問が発生。『WebMatrix.WebData.WebSecurity』あたりを勉強しようということになり
 このあたりの情報から、どうやらパスワードをリセットする機能があること、そして以下のページ
WebSecurity.ResetPassword メソッド
http://msdn.microsoft.com/ja-jp/library/webmatrix.webdata.websecurity.resetpassword(v=vs.111).aspx
ここの「説明」に以下の記述がありました。
 
ユーザーが自分のパスワードを忘れた場合、ユーザーは新しいパスワードを要求できます。
新しいパスワードを提供するには、次の手順を実行します。
1.ユーザーが電子メール アドレスを入力できるフィールドを含むパスワード リセット ページを作成します。
2.ユーザーがパスワード リセット ページで電子メール アドレスを入力した場合は、
  電子メール アドレスが有効なユーザーを表していることを確認します。
  有効なユーザーであることを確認したら、
  GeneratePasswordResetToken(String, Int32) メソッドを呼び出してパスワード リセット トークンを生成します。
3.サイトの確認ページを指し、リンクの URL のクエリ文字列パラメーターとしてトークンを含むハイパーリンクを作成します。
4.リンクを電子メール メッセージでユーザーに送信します。
  電子メール メッセージを受信したユーザーは、リンクをクリックして確認ページを呼び出します。
5.URL パラメーターからトークンを抽出し、ユーザーが新しいパスワードを入力できるようにする確認ページを作成します。
6.ユーザーが新しいパスワードを送信したら、ResetPassword(String, String) メソッドを呼び出して、
  パスワード リセット トークンと新しいパスワードを渡します。
  トークンが有効である場合、パスワードはリセットされます。
  トークンが有効ではない場合 (有効期限が切れている場合など) は、エラー メッセージを表示します。
 
これで行こうと思ったんですが、その時点ではまだメール環境が整っていなかったのでしばらく棚上げ状態にしていました。今回メール環境も用意できたので、頑張ってみようということになりました。
そこで、上記のページを再度読み直し、パスワードリセットの全体のフローは把握できたのですが、具体的なことは記載されていない、Web Matrixの勉強が必要なのかなと思い、考えあぐねていたところ、以下の素晴らしいページに遭遇することができました。ここに全てが揃っています。感謝感激です。
 
徒然なブログ WebMatrix.WebData.WebSecurity を利用したユーザー認証(その1)
http://www.makcraft.com/blog/meditation/2011/06/06/user-authentication-using-webmatrix-webdata-websecurity-1/
徒然なブログ WebMatrix.WebData.WebSecurity を利用したユーザー認証(その2)
http://www.makcraft.com/blog/meditation/2011/06/13/user-authentication-using-webmatrix-webdata-websecurity-2/
SMTP Over SSL 接続で配送依頼を行う DLL
http://www.makcraft.com/blog/meditation/2011/05/08/dll-that-does-delivery-request-by-smtp-over-ssl/
SMTP Over SSL 接続で配送依頼を行う DLL の更新
http://www.makcraft.com/blog/meditation/2011/05/20/update-smtp-over-ssl-dll/
MakCraft SmtpOverSsl Version 1.0.3 [2011年5月24日]
http://www.makcraft.com/tools/4-programs/15-smtpoverssl.html
 
ということで、MVC4でのパスワードのリセット機能は上記のページから全て入手できます。とは言っても、私の場合、多少の調整が必要でした。以下に少しだけ変更をかけた部分についてメモを残しておきます。
 
まず、こちらの環境は、先にちょっと触れたように、MVCの標準テンプレートから生成したプロジェクトで、テーブル[UserProfile]に[Email]というカラムを追加し、ユーザー登録では[ユーザー名]、[パスワード]、[Email]を入力しデータベースに格納するようになってます。テーブル[UserProfile]の主キーは自動的に連番で採番される[UserId]です。「徒然なブログ」の例はWeb Matrixのスターターサンプルのようで、[UserProfile]は[UserId]と[Email]で構成されていて、主キーの[UserId]の扱いは同じです。
上記のような仕様の違いから、こちらの環境では、リセットを指示するページでは[ユーザー名]と[Email]を入力しデータベースに登録されている情報と一致するかのチェックを入れました。また、パスワードのリセット指示ページへは、ログインページからのリンクで進むかたちをとりました。
画面はこんな感じです。
<ユーザー登録ページ>

f:id:SannomiyaNotes:20130105102145p:plain

標準にメールアドレスの入力を追加

<ログインページ>

f:id:SannomiyaNotes:20130105103010p:plain

「パスワードをお忘れの場合はパスワードをリセットしてください。」のリンクを追加。

<リセット指示ページ>

f:id:SannomiyaNotes:20130105103358p:plain

ユーザー名とメールアドレスを入力

データベース内のテーブル[UserProfile]と一致することをチェックし、OKなら

パスワード リセット トークンを生成(WebSecurity.GeneratePasswordResetToken(model.UserName))
しそのトークンを含むハイパーリンクを作成しメールで送信。
メールの送信部分には「SmtpOverSsl」を利用させてもらってます。
<送信連絡ページ>

f:id:SannomiyaNotes:20130105104349p:plain

<リセット情報メール>

f:id:SannomiyaNotes:20130106090555p:plain

ハイパーリンクは[Account]コントローラの[PasswordReset]メソッド。その後ろに[?resetToken=....]のパラメータで構成されています。

このハイパーリンクをクリックすると

<新しいパスワードの登録ページ>

f:id:SannomiyaNotes:20130106091348p:plain

新しいパスワードを入力して[リセット]クリックで、WebSecurity.ResetPasswordが呼び出され、新しいパスワードが登録され

f:id:SannomiyaNotes:20130106091907p:plain

これで新しいパスワードでログインが可能になります。

 

以上、パスワードのリセット機能は、ほぼ「徒然なブログ」からいただいたスクリプトやdllで構築することができました。

MVC4で動作させるために少し変更した部分は、

1.SMTP 接続の設定

上記ブログでは、プロジェクト直下に「_AppStart.cshtml」を追加しそこに記述していますが、私の場合は、コントローラから呼び出すスクリプトでセットするようにしました。

2.View

[ForgotPassword.cshtml]と[PasswordReset.cshtml]のjavascriptの読み込み部分を

@Scripts.Render("~/bundles/jquery")
@Scripts.Render("~/bundles/jqueryval")
とバンドル機能を使うようにしました。

あと、見た目のデザイン、と[UserProfile]の仕様の異なる部分の調整を行いましたが、大きくはこの2点の変更を行うことで完了することができました。

今回は以上です。