• [翻译]ASP.NET MVC 3 开发的20个秘诀(六)[20 Recipes for Programming MVC 3]:找回忘记的密码


    议题

    您或者在您网站的注册的某个用户,无法想起自己的密码了,需要有一种方法能找回它。

     

    解决方案

    在AccountController控制器中添加一个新的动作和视图,以便用户可以找回他们的密码。利用Membership类搜索和匹配用户,并发送一个包含密码的电子邮件。

    讨论

    默认情况下,MVC Internet应用程序使用的是无法逆向转换的单向哈希算法。在下面的例子中,默认是双向散列加密方式。这种方式并不是很安全,但是在用户忘记密码时可以避免强迫用户修改密码。

    先在Web.config文件中调整Membership节点的设置: 

    <?xml version="1.0"?>
    <configuration>
    ...
    <system.web>
    ...
    <membership>
    <providers>
    <clear />
    <add name="AspNetSqlMembershipProvider" type=
    "System.Web.Security.SqlMembershipProvider"

    connectionStringName
    ="ApplicationServices"
    enablePasswordRetrieval
    ="true" enablePasswordReset=
    "false"
    requiresQuestionAndAnswer="false"
    requiresUniqueEmail
    ="false" passwordFormat=
    "Encrypted"
    maxInvalidPasswordAttempts="5"
    minRequiredPasswordLength
    ="6"
    minRequiredNonalphanumericCharacters
    ="0"
    passwordAttemptWindow
    ="10" applicationName="/" />
    </providers>
    </membership>
    <machineKey
    validationKey=
    "2CF9FF841A23366CFA5D655790D9308656B1F7532C0B95B5C067F80C45E59875
    E2F3D68DAC63B5024C31D974D4BE151341FB8A31FC4BC3705DF5398B553FC3C3"

    decryptionKey
    ="8E71407B62F47CCA3AAA6546B3880E1A0EF9833700
    E0A0C511710F537E64B8B6"
    validation="SHA1" decryption="AES" />
    ...
    </system.web>
    ...
    </configuration>

    针对上面的设置代码,我们四个更改:

    1. 将enablePasswordRetrieval更改为True;
    2. 将enablePasswordReset更改为false;
    3. 添加passwordFormat="Encrypted";
    4. 生成加密的machineKey; 

    配置信息修改完毕后,在AccountModels.cs类中添加一个新的动作并创建忘记密码的视图:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using System.Globalization;
    using System.Web.Mvc;
    using System.Web.Security;

    namespace MvcApplication4.Models
    {
    public class ChangePasswordModel
    {
    ...
    }
    public class LogOnModel
    {
    ...
    }
    public class RegisterModel
    {
    ...
    }
    public class ForgotPasswordModel
    {
    [Required]
    [DataType(DataType.EmailAddress)]
    [Display(Name = "Email address")]
    public string Email { get; set; }
    }
    }

    在创建新视图之前,应用程序必须先编译。单击“生成”->“生成解决方案”或按F6。编译完成之后,展开Views文件夹,右键单击“Account”文件夹,选择“添加”->“视图”(如图1-4)。视图名称更改为“ForgotPassword”,选中“创建强类型视图”选项,从“模型类”下拉框中选择先前创建的“ForgotPasswordModel”,然后点击“添加”。 

    视图创建后,添加一个基本的表单,表单接受用户输入注册时填写的电子邮件地址: 

    @model MvcApplication4.Models.ForgotPasswordModel
    @{

    ViewBag.Title = "ForgotPassword";
    }

    <h2>ForgotPassword</h2>
    <p>
    Use the form below to retrieve your password.
    </p>
    <script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
    @using (Html.BeginForm()) {

    @Html.ValidationSummary(true, "Password retrieval was unsuccessful. Please correct the errors and try again.")

    <div>
    <fieldset>
    <legend>Account Information</legend>
    <div class="editor-label">
    @Html.LabelFor(m => m.Email)
    </div>

    <div class="editor-field">
    @Html.TextBoxFor(m => m.Email)
    @Html.ValidationMessageFor(m => m.Email)
    </div>

    <p>
    <input type="submit" value="Retrieve Password" />
    </p>
    </fieldset>
    </div>
    }

    下面将在之前创建的MailClient类中添加一个新方法,以实现发送用户忘记的密码: 

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Net.Mail;
    using System.Net;
    using System.Configuration;

    namespace MvcApplication4.Utils
    {
    public class MailClient
    {
    private static readonly SmtpClient Client;
    static MailClient()
    {
    ...
    }

    private static bool SendMessage(string from, string to,
    string subject, string body)
    {
    ...
    }

    public static bool SendWelcome(string email)
    {
    ...
    }

    public static bool SendLostPassword(string email,
    string password)
    {
    string body = "Your password is: " + password;
    return SendMessage("no-reply@no-reply.com", email,
    "Lost Password", body);
    }
    }
    }

    这个方法与上一个方法(*译者注:发送欢迎邮件的方法)十分相似,只是又添加了一个参数 --- 用户的密码。这个密码将被添加到电子邮件的内容中并发送给用户。

    最后在AccountController中添加两个ForgotPassword方法,第一个方法是默认载入时动作,第二是在用户填写完电子邮件地址后,接受回发数据的动作,他会从数据库中通过搜索并匹配电子邮件地址找到用户,然后将用户密码通过这个地址发给用户。 

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    using System.Web.Routing;
    using System.Web.Security;
    using MvcApplication4.Models;
    using MvcApplication4.Utils;

    namespace MvcApplication4.Controllers
    {
    public class AccountController : Controller
    {
    ...
    //
    // Get: /Account/ForgotPassword
    public ActionResult ForgotPassword()
    {
    return View();
    }

    //
    // Post: /Account/ForgotPassword
    [HttpPost]
    public ActionResult ForgotPassword(
    ForgotPasswordModel model)
    {
    if (ModelState.IsValid)
    {
    MembershipUserCollection users =
    Membership.FindUsersByEmail(model.Email);
    if (users.Count > 0)
    {
    foreach (MembershipUser user in users)
    {
    MailClient.SendLostPassword(model.Email,
    user.GetPassword());
    }
    return RedirectToAction("LogOn");
    }
    }
    // If we got this far, something failed,
    // redisplay form
    return View(model);
    }
    ...
    }

    }

    在之前的两个秘诀中,只是给用户发送了一些基本信息。将MailMessage的isBodyHtml设置为True,通过简单的扩展增强就可以发送HTML或者更复杂的内容给用户。

    参考

    Membership.Providers Property 原书地址 书籍源代码

  • 相关阅读:
    最短路径问题大总结(提纲)
    单源最短路——Bellman-Ford算法
    多源最短路——Floyd算法
    Bracket Sequences Concatenation Problem括号序列拼接问题(栈+map+思维)
    数位DP
    C++ string中的find()函数
    Planning The Expedition(暴力枚举+map迭代器)
    8月5号团队赛补题
    8月3号水题走一波-个人赛五
    Walking Between Houses(贪心+思维)
  • 原文地址:https://www.cnblogs.com/o2ds/p/2283496.html
Copyright © 2020-2023  润新知