当前位置: 首页 > ds >正文

ASP.NET Core Identity 框架中实现密码重置

文章目录

  • 前言
  • 一、密码重置流程原理
  • 二、实现步骤
    • 1)安装 NuGet 包
    • 2)配置邮箱(示例使用 MailKit )
    • 3)实现邮件发送类
    • 4)注册服务
    • 5)创建密码重置端点(控制器Controller)
  • 三、关键注意事项
    • 1)授权码获取
    • 2)端口选择
    • 3)编码问题
    • 4)异常处理
  • 四、常见问题排查
  • 总结


前言

密码重置功能

一、密码重置流程原理

  • 核心步骤
    • 用户请求重置密码(提供注册邮箱/用户名)
    • 系统生成密码重置令牌并发送到用户邮箱
    • 用户点击邮件中的链接,进入密码重置页面
    • 提交新密码和令牌,系统验证并更新密码
  • 关键技术
    • UserManager.GeneratePasswordResetTokenAsync() - 生成加密令牌
    • UserManager.ResetPasswordAsync() - 验证令牌并更新密码
    • 邮件服务集成(SMTP 或第三方服务)

二、实现步骤

1)安装 NuGet 包

  1. 安装MailKit
    Install-Package MailKit
    

2)配置邮箱(示例使用 MailKit )

  1. appsettings.json

      "EmailSettings": {"SmtpServer": "smtp.163.com","Port": 465, //465"UserName": "XXX@163.com","Password": "DJgaznENCZByW4kW", //16位授权码(qq邮箱授权码或网易邮箱授权码,不是邮箱密码)"FromAddress": "XXX@163.com"}
    
  2. EmailSettings.cs邮箱配置类

    namespace IdentityProject.Entity
    {public class EmailSettings{public string SmtpServer { get; set; }public int Port { get; set; }public string UserName { get; set; }public string Password { get; set; }public string FromAddress { get; set; }}
    }
    

3)实现邮件发送类

  1. 代码如下(示例):
    using IdentityProject.Entity;
    using Microsoft.AspNetCore.Identity.UI.Services;
    using Microsoft.Extensions.Options;
    using MimeKit;
    using System.Net;
    using System.Net.Http;
    using System.Net.Mail;namespace IdentityProject.Service
    {public class EmailSender : IEmailSender{private readonly EmailSettings _emailSettings;public EmailSender(IOptions<EmailSettings> emailSettings){_emailSettings = emailSettings.Value;}public async Task SendEmailAsync(string email, string subject, string htmlMessage){// 创建邮件对象var message = new MimeMessage();message.From.Add(new MailboxAddress("测试邮箱",//邮箱昵称_emailSettings.UserName));message.To.Add(MailboxAddress.Parse(email));message.Subject = subject;// 构建HTML正文var bodyBuilder = new BodyBuilder{HtmlBody = htmlMessage,TextBody = "您的邮件客户端不支持HTML显示"};message.Body = bodyBuilder.ToMessageBody();// 配置SMTP客户端using var client = new MailKit.Net.Smtp.SmtpClient();// 强制使用 TLS 1.2client.SslProtocols = System.Security.Authentication.SslProtocols.Tls12;await client.ConnectAsync(_emailSettings.SmtpServer,_emailSettings.Port,true);// 认证await client.AuthenticateAsync(_emailSettings.UserName,_emailSettings.Password);// 发送邮件await client.SendAsync(message);await client.DisconnectAsync(true);}}
    }

4)注册服务

  1. 代码如下(示例):
    builder.Services.Configure<EmailSettings>(builder.Configuration.GetSection("EmailSettings"));
    builder.Services.AddScoped<IEmailSender, EmailSender>();
    //调整令牌有效期(默认1天)
    builder.Services.Configure<DataProtectionTokenProviderOptions>(options =>
    {options.TokenLifespan = TimeSpan.FromHours(2); // 设置为2小时
    });
    

5)创建密码重置端点(控制器Controller)

  1. 示例代码AccountController.cs
    using IdentityProject.Entity;
    using Microsoft.AspNetCore.Http;
    using Microsoft.AspNetCore.Identity;
    using Microsoft.AspNetCore.Identity.UI.Services;
    using Microsoft.AspNetCore.Mvc;
    using System.Net;namespace IdentityProject.Controllers
    {[Route("api/[controller]/[action]")][ApiController]public class AccountController : ControllerBase{private readonly UserManager<ApplicationUser> _userManager;private readonly IEmailSender _emailSender;public AccountController(UserManager<ApplicationUser> userManager, IEmailSender emailSender){_userManager = userManager;_emailSender = emailSender;}/// <summary>/// 请求重置密码/// </summary>/// <param name="model"></param>/// <returns></returns>[HttpPost]public async Task<IActionResult> ForgotPassword([FromBody] ForgotPasswordRequest model){ var user=await _userManager.FindByEmailAsync(model.Email);var user1 = await _userManager.FindByNameAsync("LGF");if (user == null) return Ok();var token=await _userManager.GeneratePasswordResetTokenAsync(user);var resetLink= $"https://your@domain.com/reset-password?email={model.Email}&token={WebUtility.UrlEncode(token)}";await _emailSender.SendEmailAsync(model.Email, "重置密码", $"请点击链接重置密码:<a href='{resetLink}'>{resetLink}</a>");return Ok();}//设置新密码[HttpPost("reset-password")]public async Task<IActionResult> ResetPassword([FromBody] ResetPasswordRequest model){ApplicationUser user = await _userManager.FindByEmailAsync(model.Email);if (user == null) return BadRequest("用户不存在");var result = await _userManager.ResetPasswordAsync(user, model.Token, model.NewPassword);return result.Succeeded ? Ok() : BadRequest(result.Errors);}}
    }
    
    namespace IdentityProject.Entity
    {public class ForgotPasswordRequest{public string Email { get; set; }}
    }
    
    namespace IdentityProject.Entity
    {public class ResetPasswordRequest{public string Email { get; set; }public string Token { get; set; }public string NewPassword { get; set; }}
    }
    

三、关键注意事项

1)授权码获取

  • 登录163邮箱→POP3/SMTP/IMAP→开启服务(IMAP/SMTP服务)→授权密码管理→新增授权密码

2)端口选择

端口加密方式MailKit 参数
465SSLuseSsl: true
587TLSuseSsl: true

3)编码问题

  1. 如果遇到乱码,强制指定编码
    // 如果遇到乱码,强制指定编码
    message.SubjectEncoding = Encoding.UTF8;
    bodyBuilder.HtmlBody = WebUtility.HtmlEncode(htmlMessage);
    

4)异常处理

  1. 参考代码
    catch (AuthenticationException ex)
    {Console.WriteLine($"认证失败: {ex.Message}");
    }
    catch (SmtpCommandException ex)
    {Console.WriteLine($"SMTP错误 (状态码: {ex.StatusCode}): {ex.Message}");
    }
    catch (IOException ex)
    {Console.WriteLine($"网络错误: {ex.Message}");
    }
    

四、常见问题排查

  1. 问题 1:超时无法连接
    增加超时设置
    client.Timeout = 30000; // 30秒
    
  2. 问题 2:证书验证失败
    跳过证书验证(仅测试环境使用)
    client.ServerCertificateValidationCallback = (s, c, h, e) => true;
    
  3. 邮件被识别为垃圾邮件
    在邮件头中添加 X-Mailer 标识
    message.Headers.Add("X-Mailer", "MyApp Mail System");
    

总结

通过以上步骤,可实现密码重置功能

http://www.xdnf.cn/news/6094.html

相关文章:

  • 【Qt】之音视频编程2:QtAV的使用篇
  • MapReduce打包运行
  • 在Window上面添加交叉编译链 MinGW+NDK
  • blazor与硬件通信实现案例
  • PyTorch 分布式训练
  • AI时代,如何实现人机共舞?
  • 新建一个reactnative 0.72.0的项目
  • VLA 论文精读(二十二)Multi-agent Embodied AI: Advances and Future Directions
  • 【架构】RUP统一软件过程:企业级软件开发的全面指南
  • 在scala中sparkSQL连接masql并添加新数据
  • python使用OpenCV 库将视频拆解为帧并保存为图片
  • 【Mac 从 0 到 1 保姆级配置教程 15】- Python 环境一键安装与配置,就是这么的丝滑
  • 虚拟机Ubuntu系统怎么扩展容量,扩展容量后进不去系统怎么办?
  • python共享内存实际案例,传输opencv frame
  • Python面向对象编程(OOP)深度解析:从封装到继承的多维度实践
  • 【论信息系统项目的资源管理】
  • 【Git】合并和变基的区别
  • windows 强行终止进程,根据端口号
  • 人工智能技术演进:从多模态融合到智能体落地的实践探索
  • uart16550详细说明
  • 使用虚拟机Linux写程序
  • 网站开发过程中样式忽然不显示问题
  • GOOSE协议publisher上传频率
  • Playwright 安装配置文件详解
  • 爆肝整理!软件测试面试题整理(项目+接口问题)
  • OpenCV特征处理全解析:从检测到匹配的完整指南
  • 二分查找算法的思路
  • linq中 List<T>.ForEach() 与 的 Select() 方法区别——CAD c#二次开发
  • HCIP实验(BGP联邦实验)
  • 21.three官方示例+编辑器+AI快速学习webgl_buffergeometry_selective_draw