快速掌握 ASP.NET 身份认证框架 Identity - 通过邮件重置密码

这是 ASP.NET Core Identity 系列的第四篇文章,上一篇文章讲解了如何在 ASP.NET Core Identity 中实现用户登录与登出。

这篇文章讲一讲如何在 ASP.NET Core Identity 中通过邮件服务实现用户账号的密码重置。

点击上方或后方蓝字,阅读 ASP.NET Core Identity 系列合集。

本篇文章的示例项目:https://github.com/zilor-net/IdentitySample/tree/main/Sample04

1c69fcedc691a29959828e20e65f43d6.png

密码重置

用户管理中最常见的功能就是密码重置。

密码重置过程,不应该涉及系统管理员,因为用户本身应该能够独立完成整个过程。

通常,登录页面上都会为用户提供忘记密码的链接,以用来重置密码,这就是我们接下来要实现的功能。

简单地解释一下密码重置过程:

  1. 用户单击忘记密码链接,然后跳转到带有电子邮件字段的页面。

  2. 用户填写该字段后,应用程序会向该电子邮件发送密码重置的连接。

  3. 用户通过单击电子邮件的密码重置链接,此时会使用密码重置令牌,重定向到密码重置页面。

  4. 用户填充表单中的所有字段后,应用程序将重置密码,用户再被重定向到登录页面或主页。

邮件服务

示例项目中已经集成了邮件服务 「EmailService」 ,以用来帮助我们发送邮件,

具体的邮件发送的实现不是这个系列的主题,就不做过多的阐述。大家可以自己查看示例中「EmailService」项目中关于邮件发送的代码。

邮件服务通过扩展方法注册到了依赖注入框架中,其具体配置在 「appsettings.json」 中。

忘记密码

首先,我们需要创建 「忘记密码」 的视图。

「Models」 文件夹中,创建一个 「ForgotPasswordModel」 类:

public class ForgotPasswordModel
{[Display(Name = "电子邮箱")][Required(ErrorMessage = "电子邮箱不能为空")][EmailAddress(ErrorMessage = "电子邮箱格式不正确")]public string Email { get; set; }
}

它会用在「忘记密码」视图中,这里我们只需要获取用户的电子邮件,所以这里只有一个 「Email」 属性。

接下来,在 「Account」 控制器中,创建两个操作方法:

[HttpGet]
public IActionResult ForgotPassword()
{return View();
}[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> ForgotPassword(ForgotPasswordModel forgotPasswordModel)
{return View(forgotPasswordModel);
}public IActionResult ForgotPasswordConfirmation()
{return View();
}

这个套路我们已经很熟悉了,第一个 「ForgotPassword」 只是为了创建视图;第二个 「ForgotPassword」 是为了实现逻辑;「ForgotPasswordConfirmation」 则是返回确认视图。

接下来,再依次创建相关的视图:

71da9bc00456a7be63d6f51ae76777d9.png
<h1>ForgotPasswordConfirmation</h1><p>重置密码的链接已经发送到您的电子邮箱!
</p>

然后在 「Login」 视图中,添加忘记密码的链接:

<div class="form-group"><a asp-action="ForgotPassword">忘记密码</a>
</div>

现在,让我们来实现忘记密码的逻辑:

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> ForgotPassword([FromServices]IEmailSender emailSender, ForgotPasswordModel forgotPasswordModel)
{if (!ModelState.IsValid)return View(forgotPasswordModel);var user = await _userManager.FindByEmailAsync(forgotPasswordModel.Email);if (user == null)return RedirectToAction(nameof(ForgotPasswordConfirmation));var token = await _userManager.GeneratePasswordResetTokenAsync(user);var callback = Url.Action(nameof(ResetPassword), "Account", new { token, email = user.Email }, Request.Scheme);var message = new Message(new string[] { user.Email }, "重置密码", callback, null);await emailSender.SendEmailAsync(message);return RedirectToAction(nameof(ForgotPasswordConfirmation));
}

如果模型有效,就通过用户的电子邮件,从数据库中获取用户。

如果不存在,只需将该用户,重定向到邮件已发送的确认页面,而不是创建用户不存在的消息。

这么做主要是出于安全考虑,以防止有人利用这个功能,验证用户名的有效性。

如果用户存在,就通过 「GeneratePasswordResetTokenAsync」 方法,生成一个令牌,并创建一个回调链接,到我们将用于重置密码逻辑的操作。

最后,我们向用户提供的电子邮件,发送邮件消息,并将用户重定向到确认页面。

现在,程序还无法创建令牌,因为我们还没有注册令牌服务,这需要在注册 「Identity」 方法时进行注册:

builder.Services.AddIdentity<User, IdentityRole>().AddEntityFrameworkStores<ApplicationContext>().AddDefaultTokenProviders();

如果我们希望密码重置令牌只在有限的时间内有效,例如: 2小时,那我们还需要配置令牌生存期:

builder.Services.Configure<DataProtectionTokenProviderOptions>(opt =>opt.TokenLifespan = TimeSpan.FromHours(2));

重置密码

接着,我们来实现 「ResetPassword」 重置密码的操作方法,创建一个 「ResetPasswordModel」 类:

public class ResetPasswordModel
{[Display(Name = "密码")][Required(ErrorMessage = "密码不能为空")][DataType(DataType.Password)]public string Password { get; set; }[Display(Name = "确认密码")][DataType(DataType.Password)][Compare("Password", ErrorMessage = "密码与确认密码不匹配。")]public string ConfirmPassword { get; set; }public string Email { get; set; }public string Token { get; set; }
}

然后,在 「Account」 控制器中,创建 「ResetPassword」 操作方法:

[HttpGet]
public IActionResult ResetPassword(string token, string email)
{var model = new ResetPasswordModel { Token = token, Email = email };return View(model);
}[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> ResetPassword(ResetPasswordModel resetPasswordModel)
{return View();
}[HttpGet]
public IActionResult ResetPasswordConfirmation()
{return View();
}

这里与 「ForgotPassword」 操作类似。

「HttpGet」ResetPassword操作会接受来自电子邮件中,密码重置连接的请求,提取令牌和电子邮件,并创建一个视图。

「HttpPost」ResetPassword操作是处理重置密码的逻辑。

ResetPasswordConfirmation只是一个密码重置的确认视图。

依次创建这些视图:

ef15eeda40f883da8b5aea60a7e6d735.png

需要注意的是,我们需要把 「Email」「Token」 两个字段隐藏起来,因为这两个值由应用提供,不需要用户设置:

<input type="hidden" asp-for="Email" class="form-control" />
<input type="hidden" asp-for="Token" class="form-control" />

「ResetPasswordConfirmation」 视图:

<h1>ResetPasswordConfirmation</h1>
<p>您的密码已经重置. 请点击这里 <a asp-action="Login"> 登录 </a>!
</p>

最后,再来修改 「POST」ResetPassword 操作方法:

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> ResetPassword(ResetPasswordModel resetPasswordModel)
{if (!ModelState.IsValid)return View(resetPasswordModel);var user = await _userManager.FindByEmailAsync(resetPasswordModel.Email);if (user == null)RedirectToAction(nameof(ResetPasswordConfirmation));var resetPassResult = await _userManager.ResetPasswordAsync(user, resetPasswordModel.Token, resetPasswordModel.Password);if(!resetPassResult.Succeeded){foreach (var error in resetPassResult.Errors){ModelState.TryAddModelError(error.Code, error.Description);}return View();}return RedirectToAction(nameof(ResetPasswordConfirmation));
}

首先,检查模型的有效性,以及用户是否存在于数据库中。

之后,使用 「ResetPasswordAsync」 方法,执行密码重置操作。

如果操作失败,就向模型状态添加错误并返回视图。否则,我们将用户重定向到确认页面。

需要注意的是,如果想要测试最终效果,邮件服务的配置以及用户的邮件地址都必须是真实有效的。

小结

现在,我们已经实现了用户通过电子邮件,重置密码的功能,下篇文章将会讲解如何在用户注册时,必须确认电子邮件是否有效的功能。

更多精彩内容,请关注我▼▼

d4c04b351f225756b5b069f5f4d640b1.gif

如果喜欢我的文章,那么

在看和转发是对我最大的支持!

(戳下面蓝字阅读)

e241706d9b4757affda5ccba11f4ad6b.png

推荐关注微信公众号:码侠江湖

                        d387e970d609b4285ba5cf0be12a66f4.png觉得不错,点个在看再走哟

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/285579.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[.net 面向对象程序设计深入](4)MVC 6 —— 谈谈MVC的版本变迁及新版本6.0发展方向...

[.net 面向对象程序设计深入]&#xff08;4&#xff09;MVC 6 ——谈谈MVC的版本变迁及新版本6.0发展方向 1.关于MVC 在本篇中不再详细介绍MVC的基础概念&#xff0c;这些东西百度要比我写的全面多了&#xff0c;MVC从1.0到5.0的时间也不短了&#xff0c;很多人只是按照范例去使…

C语言试题101之输入三个整数 x,y,z,请把这三个数由小到大输出

✅作者简介:大家好我是码莎拉蒂,CSDN博客专家🥇🥇🥇 📃个人主页:个人主页 🔥系列专栏:C语言试题200例 💬推荐一款模拟面试、刷题神器👉 点击跳转进入网站 1、题目 题目:输入三个整数 x,y,z,请把这三个数由小到大输出 分析:想办法把最小的数放到 x 上,先…

[转]史上最全的后端技术大全,你都了解哪些技术呢?

导语&#xff1a;工欲善其事&#xff0c;必先利其器&#xff1b;士欲宣其义&#xff0c;必先读其书。后台开发作为互联网技术领域的掌上明珠&#xff0c;一直都是开发者们的追逐的高峰。本文将从后台开发所涉及到的技术术语出发&#xff0c;基于系统开发、架构设计、网络通信等…

【专升本计算机】2021年甘肃省专升本计算机全真模拟试题(二)

【专升本计算机】2021年甘肃省专升本计算机全真模拟试题(一) 【专升本计算机】2021年甘肃省专升本计算机全真模拟试题(二) 【专升本计算机】2021年甘肃省专升本计算机全真模拟试题(三) 【专升本计算机】2021年甘肃省专升本计算机全真模拟试题(四) 【专升本计算机】2021…

WPF 开源控件库Extended WPF Toolkit介绍(经典)

01—Extended WPF Toolkit介绍Extended WPF Toolkit 可以说是WPF Toolkit 的一个补充&#xff0c;Extended WPF Toolkit包含了标准的WPF Toolkit里没有的Windows Presentation Foundation&#xff08;WPF&#xff09;控件、工具和组件。Extended WPF Toolkit是创建下一代Window…

C语言试题102之用*号输出字母 C 的图案

✅作者简介:大家好我是码莎拉蒂,CSDN博客专家🥇🥇🥇 📃个人主页:个人主页 🔥系列专栏:C语言试题200例 💬推荐一款模拟面试、刷题神器👉 点击跳转进入网站 1、题目 题目:用号输出字母 C 的图案 分析:可先用’号在纸上写出字母 C,再分行输出。 2 、温馨提…

【专升本计算机】2021年甘肃省专升本计算机全真模拟试题(三)

【专升本计算机】2021年甘肃省专升本计算机全真模拟试题(一) 【专升本计算机】2021年甘肃省专升本计算机全真模拟试题(二) 【专升本计算机】2021年甘肃省专升本计算机全真模拟试题(三) 【专升本计算机】2021年甘肃省专升本计算机全真模拟试题(四) 【专升本计算机】2021…

WPF 用代码实现WrapPanel右侧自动对齐(解决多余空白问题)

未处理前效果&#xff1a; 处理后效果&#xff1a; <Border Background"{StaticResource BorderBg}" BorderThickness"2" BorderBrush"{StaticResource BorderBrush}" CornerRadius"5" Padding"5" x:Name"SvK…

.NET 中的引用程序集

.NET 中的引用程序集Intro在 .NET 里有一种特殊的程序集叫做 ReferenceAssembly(引用程序集)&#xff0c;引用程序集&#xff08;Reference Assemblies&#xff09; 是一种特殊类型的程序集&#xff0c;它只包含表示库的公共 API 所需的最少元数据量。它们包括在生成工具中引用…

【专升本计算机】2021年甘肃省专升本计算机全真模拟试题(四)

【专升本计算机】2021年甘肃省专升本计算机全真模拟试题(一) 【专升本计算机】2021年甘肃省专升本计算机全真模拟试题(二) 【专升本计算机】2021年甘肃省专升本计算机全真模拟试题(三) 【专升本计算机】2021年甘肃省专升本计算机全真模拟试题(四) 【专升本计算机】2021…

C语言试题105之要求输出国际象棋棋盘

✅作者简介:大家好我是码莎拉蒂,CSDN博客专家🥇🥇🥇 📃个人主页:个人主页 🔥系列专栏:C语言试题200例 💬推荐一款模拟面试、刷题神器👉 点击跳转进入网站 1、题目 题目:要求输出国际象棋棋盘。 分析:用 i 控制行,j 来控制列,根据 i+j 的和的变化来控制…

一个js的动画,以前以为只有flash可以实现

11年刚干这行的时候&#xff0c;看到这种什么百叶窗的动画&#xff0c;以为都是flash实现的&#xff0c;最近突然灵光一闪&#xff0c;想到了用js实现&#xff08;虽然我不是做前端的&#xff0c;本人做.net&#xff09;。代码虽然实现了&#xff0c;但是比较乱&#xff0c;先上…

[转]docker入门(利用docker部署web应用)

前言:本课程是在慕课网上学习 第一个docker化的java应用 课程时所做的笔记,供本人复习之用 目录 第一章 什么是docker 1.1 docker的发展史 1.2 docker国内应用史 1.3 什么是Docker 第二章 了解docker 2.1 docker思想 2.1.1 集装箱 2.1.2 标准化 2.1.3 隔离 2.2 dock…

【专升本计算机】2021年甘肃省专升本计算机全真模拟试题(五)

【专升本计算机】2021年甘肃省专升本计算机全真模拟试题(一) 【专升本计算机】2021年甘肃省专升本计算机全真模拟试题(二) 【专升本计算机】2021年甘肃省专升本计算机全真模拟试题(三) 【专升本计算机】2021年甘肃省专升本计算机全真模拟试题(四) 【专升本计算机】2021…

如何让 EF Core 6 支持 DateOnly 类型

前言上次&#xff0c;我们发现《DateOnly 和 TimeOnly 类型居然不能序列化》。但问题还不仅仅如此。问题重现假设有下列实体类&#xff1a;public class User {public int Id { get; set; }public string Name { get; set; } public DateOnly Birthday { get; set; } }由…

[转]Python 列表(List) 的三种遍历(序号和值)方法

if __name__ __main__:list [html, js, css, python]for i in list:print(list.index(i), i)# 方法1print( 遍历列表方法1&#xff1a;)for i in list:print ("序号&#xff1a;%s 值&#xff1a;%s" % (list.index(i) 1, i))print (\n遍历列表方法2&#xff1a;)…

C语言试题103之输出特殊图案,请在 c 环境中运行,看一看

✅作者简介:大家好我是码莎拉蒂,CSDN博客专家🥇🥇🥇 📃个人主页:个人主页 🔥系列专栏:C语言试题200例 💬推荐一款模拟面试、刷题神器👉 点击跳转进入网站 1、题目 题目:输出特殊图案,请在 c 环境中运行,看一看 2 、温馨提示 想获取更多C语言题目请猛搓这…

Kafka学习征途:基于Docker搭建Kafka环境

【Kafka】| 总结/Edison Zhou1准备工作这里我们使用一台Linux CentOS系统的服务器来模拟三个Kafka Broker的伪集群&#xff08;即一台server上开三个不同端口&#xff09;环境用于学习测试&#xff0c;大概的准备工作有两个&#xff1a;安装Docker# wget https://mirrors.aliyu…

C语言试题104之输出 9乘9 口诀

✅作者简介:大家好我是码莎拉蒂,CSDN博客专家🥇🥇🥇 📃个人主页:个人主页 🔥系列专栏:C语言试题200例 💬推荐一款模拟面试、刷题神器👉 点击跳转进入网站 1、题目 题目:输出 9乘9 口诀。 分析:分行与列考虑,共 9 行 9 列,i 控制行,j 控制列 2 、温馨提…

【Envi风暴】基于ENVI平台提取ASTER DEM完整操作步骤(附案例数据)

本文讲解在Envi平台上,基于Aster影像数据,提取DEM的完整操作流程及注意事项,附实验数据下载练习。 文章目录 一、内容和目的二、提取DEM的原理三、ENVI平台提取DEM流程四、DEM质量评估五、注意事项六、案例数据下载地址一、内容和目的 采用ASTER立体像对提取DEM,数据源: …