在ASP.NET MVC WebMatrix中忘记密码+电子邮件确认

时间:2012-11-03 19:58:16

标签: asp.net-mvc

看来这两个功能在WebMatrix代码中有一组辅助函数和模式可供使用。但是,没有控制器方法或视图来完成它,所以你必须自己实现。

在我可以将此代码复制到我的应用程序的任何地方是否有任何样本?我正在寻找一些东西:

  • 生成忘记密码电子邮件
  • 生成确认电子邮件
  • 忘记密码视图+控制器方法
  • 重新发送确认电子邮件视图+控制器方法

1 个答案:

答案 0 :(得分:15)

FORGOT PASSWORD FUNCTIONALITY

前几天我试图在asp.net MVC 4中创建一个“忘记密码功能”。我googled in and out但无法获得最佳解决方案。我终于找到了出路。 15个简单的步骤

第1部分  通过电子邮件发送密码重置信息

第1步 •创建Mvc 4 c#Internet应用程序模板:)             (将自动生成帐户和家庭控制器) •构建并运行您的项目。注册并登录。 (将生成简单的成员资格表)

                        Everything working fine?

第2步 •哎呀!!注册时他们不会询问我们的电子邮件ID!为了向用户发送密码令牌,我们需要他们的电子邮件ID!那么让我们在数据库中进行一些更改转到服务器资源管理器! (如果你找不到它你可以按Ctrl + alt + S) •展开“数据连接”,您将看到几个表。打开用户档案表。 添加以下列:

  1. EmailId nvarchar(max) 2.Details nvarchar(max)
  2. 第3步 •现在转到解决方案资源管理器...模型...帐户模型...注册模型 •为电子邮件ID和详细信息添加这两个属性

    //new properties
        [Required]
        [Display(Name="Email ID")]
        public string EmailId { get; set; }
    
        [Required]
        [Display(Name = "About Yourself")]
        public string Details { get; set; }
    

    第4步 •现在转到Solution Explorer ... Views ... Account Views ... Register.cshtml view •添加这两个属性以允许用户输入电子邮件ID和其他详细信息。

  3.                 @ Html.LabelFor(m => m.EmailId)                 @ Html.TextBoxFor(m => m.EmailId)             
  4.             
  5.                 @ Html.LabelFor(m => m.Details)                 @ Html.TextBoxFor(m => m.Details)             
  6. 第5步 •现在转到解决方案资源管理器...控制器...帐户控制器...注册控制器操作方法的发布版本 •添加这些属性以允许用户输入电子邮件ID和其他详细信息。更改将突出显示。

    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public ActionResult Register(RegisterModel model)
    {
        if (ModelState.IsValid)
        {
            // Attempt to register the user
            try
            {
                WebSecurity.CreateUserAndAccount(model.UserName, model.Password, new { EmailId = model.EmailId, Details = model.Details});
    
                WebSecurity.Login(model.UserName, model.Password);
                return RedirectToAction("Index", "Home");
            }
            catch (MembershipCreateUserException e)
            {
                ModelState.AddModelError("", ErrorCodeToString(e.StatusCode));
            }
        }
    
        // If we got this far, something failed, redisplay form
        return View(model);
    }
    

    为什么我们不再建立和运行我们的项目?注册并填写详细信息。现在还要求您指定电子邮件地址。添加这些属性以允许用户输入电子邮件ID和其他详细信息。

    转到服务器资源管理器并右键单击“用户配置文件”表并选择“显示表格数据”您可以查看您输入的详细信息以进行验证。

    第6步 •现在让我们实现密码重置功能转到帐户控制器并创建以下控制器操作方法(GET)

    [AllowAnonymous]
    public ActionResult ForgotPassword()
    {
        return View();
    }
    
    •    (POST)
    
    
    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public ActionResult ForgotPassword(string UserName)
    {
        //check user existance
        var user = Membership.GetUser(UserName);
        if (user == null)
        {
            TempData["Message"] = "User Not exist.";
        }
        else
        {
            //generate password token
            var token = WebSecurity.GeneratePasswordResetToken(UserName);
            //create url with above token
            var resetLink = "<a href='" + Url.Action("ResetPassword", "Account", new { un = UserName, rt = token }, "http") + "'>Reset Password</a>";
            //get user emailid
            UsersContext db = new UsersContext();
            var emailid = (from i in db.UserProfiles
                            where i.UserName == UserName
                            select i.EmailId).FirstOrDefault();
            //send mail
            string subject = "Password Reset Token";
            string body = "<b>Please find the Password Reset Token</b><br/>" + resetLink; //edit it
            try
            {
                SendEMail(emailid, subject, body);
                TempData["Message"] = "Mail Sent.";
            }
            catch (Exception ex)
            {
                TempData["Message"] = "Error occured while sending email." + ex.Message;
            }
            //only for testing
            TempData["Message"] = resetLink;
        }
    
        return View();
    }
    

    •GET控制器操作只返回视图。 •POST控制器操作: 收到用户名 验证它的存在 生成密码重置令牌 构建要通过电子邮件发送的URL。

    第7步 •右键单击忘记密码操作方法并添加视图视图页面的代码如下所示

    @{
        ViewBag.Title = "Forgot Password";
    }
    
    <h2>Forgot Password</h2>
    
    
    
    @using (Html.BeginForm())
    {
        @Html.AntiForgeryToken()
        <fieldset>
            <legend>Forgot Password Form</legend>
            <ol>
                <li>
                    @Html.Label("User Name", new { @for = "UserName" })
                    @Html.TextBox("UserName")
                    <span style="color:red;">@TempData["Message"]</span>
                </li>
            </ol>
            <input type="submit" value="Recover" />
        </fieldset>
    }
    

    •视图页面将显示一个文本框,用户可以在其中输入用户名。

    第8步 •现在转到解决方案资源管理器...模型...帐户模型...用户配置文件视图模型。变更已突出显示

    [Table("UserProfile")]
    public class UserProfile
    {
        [Key]
        [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
        public int UserId { get; set; }
        public string UserName { get; set; }
        //new properties
        public string EmailId { get; set; }
        public string Details { get; set; }
    }
    

    第9步 •现在转到解决方案资源管理器...视图...帐户...登录视图。 现在我们可以看到一个选项来恢复他的密码,以防他忘记密码。

    <ul>    
                <li>
                        @Html.ActionLink("Register", "Register") if you don't have an account.
                </li>
                <li>
                        @Html.ActionLink("Forgot Password", "ForgotPassword") if you want to recover your password.
                </li>
            </ul>
    

    第2部分  从URL

    接收密码重置信息

    第1步 •转到Solution Explorer ...控制器...帐户控制器... 创建新的重置密码操作方法 •此方法从URL接受“un”(用户名)和“rt”(密码重置令牌)。

    [AllowAnonymous]
    public ActionResult ResetPassword(string un, string rt)
    {
        UsersContext db = new UsersContext();
        //TODO: Check the un and rt matching and then perform following
        //get userid of received username
        var userid = (from i in db.UserProfiles
                        where i.UserName == un
                        select i.UserId).FirstOrDefault();
        //check userid and token matches
        bool any = (from j in db.webpages_Memberships
                    where (j.UserId == userid)
                    && (j.PasswordVerificationToken == rt)
                    //&& (j.PasswordVerificationTokenExpirationDate < DateTime.Now)
                    select j).Any();
    
        if (any == true)
        {
            //generate random password
            string newpassword = GenerateRandomPassword(6);
            //reset password
            bool response = WebSecurity.ResetPassword(rt, newpassword);
            if (response == true)
            {
                //get user emailid to send password
                var emailid = (from i in db.UserProfiles
                                where i.UserName == un
                                select i.EmailId).FirstOrDefault();
                //send email
                string subject = "New Password";
                string body = "<b>Please find the New Password</b><br/>" + newpassword; //edit it
                try
                {
                    SendEMail(emailid, subject, body);
                    TempData["Message"] = "Mail Sent.";
                }
                catch (Exception ex)
                {
                    TempData["Message"] = "Error occured while sending email." + ex.Message;
                }
    
                //display message
                TempData["Message"] = "Success! Check email we sent. Your New Password Is " + newpassword;
            }
            else
            {
                TempData["Message"] = "Hey, avoid random request on this page.";
            }
        }
        else
        {
            TempData["Message"] = "Username and token not maching.";
        }           
    
        return View();
    }
    

    第2步 •右键单击重置密码操作方法并添加视图视图页面的代码如下所示

    @{
        ViewBag.Title = "ResetPassword";
    }
    
    <h2>Password Mailed :) </h2>
    

    第3步 •转到解决方案资源管理器...模型...帐户模型... 进行以下更改。 •我们创建一个UserProfile数据库模型实例,并将db.webpages_Memberships实现为DbSet.Use'webpages_Memberships'作为模型。

    public class UsersContext : DbContext
        {
            public UsersContext()
                : base("DefaultConnection")
            {
            }
    
            public DbSet<UserProfile> UserProfiles { get; set; }
            public DbSet<webpages_Membership> webpages_Memberships { get; set; }
        }
    
        [Table("webpages_Membership")]
        public class webpages_Membership
        {
            [Key]
            public int UserId { get; set; }
            public DateTime CreateDate { get; set; }
            public string ConfirmationToken { get; set; }
            public bool IsConfirmed { get; set; }
            public DateTime LastPasswordFailureDate { get; set; }
            public int PasswordFailuresSinceLastSuccess { get; set; }
            public string Password { get; set; }
            public DateTime PasswordChangeDate { get; set; }
            public string PasswordSalt { get; set; }
            public string PasswordVerificationToken { get; set; }
            public DateTime PasswordVerificationTokenExpirationDate { get; set; }
        }
    

    第4步 •将随机密码生成功能添加到帐户控制器 •调用此方法将为用户生成随机密码

     private string GenerateRandomPassword(int length)
        {
            string allowedChars = "abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ0123456789!@$?_-*&#+";
            char[] chars = new char[length];
            Random rd = new Random();
            for (int i = 0; i < length; i++)
            {
                chars[i] = allowedChars[rd.Next(0, allowedChars.Length)];
            }
            return new string(chars);
        }
    

    第5步 •在帐户控制器中添加发送电子邮件功能。 •当用户点击忘记密码表单上的恢复按钮时,此功能将向用户发送第一封邮件。第一封邮件包含重置密码链接。当用户点击链接时。用户将被重定向到重置密码页面。新密码将再次邮寄给用户。 •您需要输入您的电子邮件地址代替XXXXX@gmail.com并写下您的密码。

    private void SendEMail(string emailid, string subject, string body)
            {
                System.Net.Mail.SmtpClient client = new System.Net.Mail.SmtpClient();
                client.DeliveryMethod = System.Net.Mail.SmtpDeliveryMethod.Network;
                client.EnableSsl = true;
                client.Host = "smtp.gmail.com";
                client.Port = 587;  
    
    
                System.Net.NetworkCredential credentials = new System.Net.NetworkCredential("xxxxx@gmail.com", "password");
                client.UseDefaultCredentials = false;
                client.Credentials = credentials;
    
                System.Net.Mail.MailMessage msg = new System.Net.Mail.MailMessage();
                msg.From = new MailAddress("xxxxx@gmail.com");
                msg.To.Add(new MailAddress(emailid));
    
                msg.Subject = subject;
                msg.IsBodyHtml = true;
                msg.Body = body;
    
                client.Send(msg);
            }