asp.net mvc使用邮箱找回密码功能的详细步骤
来源:互联网 发布:手机改图软件 编辑:程序博客网 时间:2024/06/05 12:50
背景条件:
使用的是asp.net mvc6 ,Microsoft.AspNet.Identity
如果没用Microsoft.AspNet.Identity,那这篇文章对你帮助不大。
设计步骤:
1、输入注册邮箱页面
2、验证邮箱在用户表中是否存在,如果存在,则会向用户邮箱发送一重置密码的链接,并且跳转到忘记密码确认页面。如果不存在,考虑到安全,不会提示该邮箱不存在,仍然会跳转到忘记密码确认页面,但是不会向邮箱发送邮件。
3、用户打开自己的邮箱,点击重置密码链接,跳转到重置密码页面重新设置密码
4、在重置密码页面输入新密码和确认密码,点重置按钮,重置成功后跳转到重置确认页面
一、首先是忘记密码页面
很简单,就一个电子邮件输入框,一个发送邮件按钮。
这个电子邮箱是你注册时填写的邮箱,胡乱填写个邮箱是没有用的
点发送邮件按钮。然后执行action动作。
[HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] public async Task<ActionResult> ForgotPassword(ForgotPasswordViewModel model) { if (ModelState.IsValid) { var user = await UserManager.FindByIdAsync(model.Email); //EventLog.WriteLog("" + (user == null)); //if (user == null || !(await UserManager.IsEmailConfirmedAsync(user.Id))) if (user == null) { //EventLog.WriteLog("该邮箱不存在或者未经确认"); // 请不要显示该用户不存在或者未经确认 return View("ForgotPasswordConfirmation"); } // 有关如何启用帐户确认和密码重置的详细信息,请访问 http://go.microsoft.com/fwlink/?LinkID=320771 // 发送包含此链接的电子邮件 string code = await UserManager.GeneratePasswordResetTokenAsync(user.Id); if (Request.Url != null) { var callbackUrl = Url.Action("ResetPassword", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme); //根据user.id获取到该会员的email,然后调用await this.EmailService.SendAsync(message).WithCurrentCulture()完成邮件发送 //UserManager.SendEmailAsync是一个虚方法 await UserManager.SendEmailAsync(user.Id, "重置密码", "请通过单击 <a href=\"" + callbackUrl + "\">此处</a>来重置你的密码"); } return RedirectToAction("ForgotPasswordConfirmation", "Account"); } // 如果我们进行到这一步时某个地方出错,则重新显示表单 return View(model); }
UserManager.FindByEmailAsync此方法是通过email在会员表中搜索是否有符合条件的记录。如果没有,跳转到ForgotPasswordConfirmation.cshtml页面。
如果用户存在,则使用UserManager.GeneratePasswordResetTokenAsync生成一个重设密码的token。然后用Url.Action方法拼接一个链接串,再调用UserManager.SendEmailAsync向邮箱中发送一封带重置密码链接的邮件。发送完后用RedirectToAction("ForgotPasswordConfirmation", "Account")
方法跳转到忘记密码确认页面。
二、忘记密码确认页面内容如下:
注意此方法:UserManager.SendEmailAsync,这个方法是发邮件的方法。但是如何设置才能使系统自动发送邮件还需要相应的类来实现。首先我们反编译这个方法,他在Microsoft.AspNet.Identity.Core.dll中:
public virtual async Task SendEmailAsync(TKey userId, string subject, string body){this.ThrowIfDisposed();if (this.EmailService != null){IdentityMessage message = new IdentityMessage{Destination = await this.GetEmailAsync(userId).WithCurrentCulture<string>(),Subject = subject,Body = body};await this.EmailService.SendAsync(message).WithCurrentCulture();}}
在这个反编译代码中,注意this.EmailService,这个EmailService类需要自定义,这个类中的SendAsync方法要自己实现,以便使用特定的邮箱发邮件。它需要继承IIdentityMessageService,代码如下:
public class EmailService : IIdentityMessageService { public async Task SendAsync(IdentityMessage message) { MailConfig mailConfig = (MailConfig)ConfigurationManager.GetSection("application/mail"); if (mailConfig.RequireValid) { if (1 == 0) { EventLog.WriteLog(mailConfig.EmailAddress); EventLog.WriteLog(mailConfig.EmailUserName); EventLog.WriteLog(message.Destination); } // 设置邮件内容 var mail = new MailMessage( new MailAddress(mailConfig.EmailAddress, mailConfig.EmailUserName), new MailAddress(message.Destination) ); mail.Subject = message.Subject; mail.Body = message.Body; mail.IsBodyHtml = true; mail.BodyEncoding = Encoding.UTF8; // 设置SMTP服务器 var smtp = new SmtpClient(mailConfig.SmtpServer, mailConfig.SmtpPort); smtp.UseDefaultCredentials = false; smtp.Credentials = new System.Net.NetworkCredential(mailConfig.EmailAddress, mailConfig.EmailPwd); smtp.DeliveryMethod = SmtpDeliveryMethod.Network; await smtp.SendMailAsync(mail); } await Task.FromResult(0); } }
在这里面使用了MailConfig类。代码如下:
public class MailConfig : ConfigurationSection { /// <summary> /// 注册时是否需要验证邮箱 /// </summary> [ConfigurationProperty("RequireValid", DefaultValue = "false", IsRequired = true)] public bool RequireValid { get { return (bool)this["RequireValid"]; } set { this["RequireValid"] = value; } } /// <summary> /// SMTP服务器 /// </summary> [ConfigurationProperty("SmtpServer", IsRequired = true)] public string SmtpServer { get { return (string)this["SmtpServer"]; } set { this["SmtpServer"] = value; } } /// <summary> /// 默认端口25(设为-1让系统自动设置) /// </summary> [ConfigurationProperty("SmtpPort", DefaultValue = "25", IsRequired = true)] public int SmtpPort { get { return (int)this["SmtpPort"]; } set { this["SmtpPort"] = value; } } /// <summary> /// 地址 /// </summary> [ConfigurationProperty("EmailAddress", IsRequired = true)] public string EmailAddress { get { return (string)this["EmailAddress"]; } set { this["EmailAddress"] = value; } } /// <summary> /// 账号 /// </summary> [ConfigurationProperty("EmailUserName", IsRequired = true)] public string EmailUserName { get { return (string)this["EmailUserName"]; } set { this["EmailUserName"] = value; } } /// <summary> /// 密码 /// </summary> [ConfigurationProperty("EmailPwd", IsRequired = true)] public string EmailPwd { get { return (string)this["EmailPwd"]; } set { this["EmailPwd"] = value; } } /// <summary> /// 是否使用SSL连接 /// </summary> [ConfigurationProperty("EnableSSL", DefaultValue = "false", IsRequired = false)] public bool EnableSSL { get { return (bool)this["EnableSSL"]; } set { this["EnableSSL"] = value; } } /// <summary> /// /// </summary> [ConfigurationProperty("EnablePwdCheck", DefaultValue = "false", IsRequired = false)] public bool EnablePwdCheck { get { return (bool)this["EnablePwdCheck"]; } set { this["EnablePwdCheck"] = value; } } }
web.config中相关的email配置:
<application>
<mail RequireValid="true" SmtpServer="smtp.exmail.qq.com" SmtpPort="25" EmailUserName="你的名字" EmailAddress="xxx@xx.xxx" EmailPwd="xxx" EnableSSL="false" EnablePwdCheck="false" />
</application>
至此,发邮件的相关类及方法已经介绍完了。
三、去电子邮箱查收重置密码邮件
四、打开邮箱中的邮件,点击此处链接。跳转到重置密码页面
再次输入你的邮箱,然后输入新密码及新密码确认。
相应的页面actionresult:
[AllowAnonymous] public ActionResult ResetPassword(string code, string userid) { return code == null ? View("Error") : View(); }
相应的model:
public class ResetPasswordViewModel { [Required] [StringLength(100, ErrorMessage = "{0} 必须至少包含 {2} 个字符。", MinimumLength = 6)] [DataType(DataType.Password)] [Display(Name = "密码")] public string Password { get; set; } [DataType(DataType.Password)] [Display(Name = "确认密码")] [Compare("Password", ErrorMessage = "密码和确认密码不匹配。")] public string ConfirmPassword { get; set; } public string Code { get; set; } public string UserId { get; set; } }
相应的cshtml代码,只摘一部分:
@model LMCMS.ViewModel.ResetPasswordViewModel@{ ViewBag.Title = "使用电子邮件重置密码";} <h2>@ViewBag.Title。</h2> @using (Html.BeginForm("ResetPassword", "Account", FormMethod.Post, new { @class = "form-horizontal", role = "form" })){ @Html.AntiForgeryToken() <h4>重置您的密码。</h4> <hr /> @Html.ValidationSummary("", new { @class = "text-danger" }) @Html.HiddenFor(model => model.Code) @Html.HiddenFor(Model=>Model.UserId) <div class="form-group"> @Html.LabelFor(m => m.Password, new { @class = "col-md-2 control-label" }) <div class="col-md-4 col-xs-8"> @Html.PasswordFor(m => m.Password, new { @class = "form-control" }) </div> </div> <div class="form-group"> @Html.LabelFor(m => m.ConfirmPassword, new { @class = "col-md-2 control-label" }) <div class="col-md-4 col-xs-8"> @Html.PasswordFor(m => m.ConfirmPassword, new { @class = "form-control" }) </div> </div> <div class="form-group"> <div class="col-md-offset-2 col-md-10"> <input type="submit" class="btn btn-default" value="重置" /> </div> </div>}这里的隐藏字段model.Code及Model.UserId会自动接收url中相应的变量值。
点击重置按钮后相应的处理方法:
[HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] public async Task<ActionResult> ResetPassword(ResetPasswordViewModel model) { if (!ModelState.IsValid) { return View(model); } //EventLog.WriteLog(model.Email); var user = await UserManager.FindByEmailAsync(model.UserId); //EventLog.WriteLog("" + (user == null)); if (user == null) { // 请不要显示该用户不存在 return RedirectToAction("ResetPasswordConfirmation", "Account"); } var result = await UserManager.ResetPasswordAsync(user.Id, model.Code, model.Password); if (result.Succeeded) { return RedirectToAction("ResetPasswordConfirmation", "Account"); } AddErrors(result); return View(); }
五、点击重置按钮,经过处理后,重置成功,则跳到重置密码确认页面
至此重置密码成功,可以使用新密码登录了
- asp.net mvc使用邮箱找回密码功能的详细步骤
- 邮箱找回密码功能
- .net邮箱找回密码
- asp.net 邮件找回密码功能、
- php邮箱找回密码功能
- php邮箱找回密码功能
- phpcms使用邮箱找回密码的bug
- 使用邮箱找回密码 springmvc
- thinkphp通过邮箱找回密码功能解析
- 邮箱找回密码功能实现思路
- asp.net实现密码找回
- 在yii 框架下 使用phpmailer 通过邮箱验证找回密码功能
- 找回foxmail下的邮箱密码
- 通过邮箱找回密码的实现
- 关于通过邮箱找回密码的实现
- asp.net 邮箱验证 密码
- 邮箱找回密码
- 通过邮箱找回密码
- ANdroid Studio中教你创建代码块---(续)
- 博客伊始,写着回忆
- Unix/Linux中的read和write函数
- 常用随机数工具类
- 如何在Linux服务器上设置rsync驻留服务
- asp.net mvc使用邮箱找回密码功能的详细步骤
- Android网络状态之ConnectivityManager
- 关于hosts
- CSS学习笔记1
- [LeetCode]Binary Search Tree Iterator
- 如何在linux环境下使用r语言
- win+caffe mnist实例运行(禁止转载)
- lintcode_100题
- code formatter