.Net ABP Framework 6:拦截或扩展新用户创建API(非注册接口)
在ABP 6 Angular应用中扩展用户创建API实现邮箱确认邮件发送
针对你的需求,无需直接修改ABP内部API,利用ABP框架的扩展机制即可实现目标,以下是两种常用方案:
方法一:通过领域事件监听用户创建动作
ABP在用户创建完成后会自动发布UserCreatedEvent领域事件,我们可以通过实现事件处理器来触发邮箱确认邮件的发送逻辑:
- 编写领域事件处理器类
public class UserCreatedEmailConfirmationHandler : IDomainEventHandler<UserCreatedEvent> { private readonly IUserEmailConfirmationService _emailConfirmationService; private readonly IEmailSender _emailSender; private readonly ICurrentTenant _currentTenant; public UserCreatedEmailConfirmationHandler( IUserEmailConfirmationService emailConfirmationService, IEmailSender emailSender, ICurrentTenant currentTenant) { _emailConfirmationService = emailConfirmationService; _emailSender = emailSender; _currentTenant = currentTenant; } public async Task HandleEventAsync(UserCreatedEvent eventData) { var user = eventData.User; // 跳过已确认邮箱或无邮箱的用户 if (user.EmailConfirmed || string.IsNullOrWhiteSpace(user.Email)) { return; } // 生成邮箱确认令牌 var token = await _emailConfirmationService.GenerateConfirmationTokenAsync(user); // 拼接Angular端的邮箱确认页面链接 var confirmationLink = $"https://your-angular-domain/account/confirm-email?userId={user.Id}&token={Uri.EscapeDataString(token)}&tenantId={_currentTenant.Id}"; // 发送确认邮件 await _emailSender.SendAsync( to: user.Email, subject: "请确认你的邮箱", body: $"请点击以下链接完成邮箱确认:<a href=\"{confirmationLink}\">确认邮箱</a>", isBodyHtml: true ); } }
- 在模块中注册事件处理器
在你的应用模块(例如YourProjectWebModule)的ConfigureServices方法中添加注册代码:
context.Services.AddTransient<IDomainEventHandler<UserCreatedEvent>, UserCreatedEmailConfirmationHandler>();
方法二:覆盖IdentityUserAppService的创建方法
通过替换ABP默认的用户管理应用服务,在用户创建逻辑执行完成后追加邮件发送步骤:
- 自定义IdentityUserAppService
public class CustomIdentityUserAppService : IdentityUserAppService { private readonly IUserEmailConfirmationService _emailConfirmationService; private readonly IEmailSender _emailSender; private readonly ICurrentTenant _currentTenant; public CustomIdentityUserAppService( IdentityUserManager userManager, IIdentityUserRepository userRepository, IIdentityRoleRepository roleRepository, IIdentityUserLookupService identityUserLookupService, IUserEmailConfirmationService emailConfirmationService, IEmailSender emailSender, ICurrentTenant currentTenant) : base(userManager, userRepository, roleRepository, identityUserLookupService) { _emailConfirmationService = emailConfirmationService; _emailSender = emailSender; _currentTenant = currentTenant; } public override async Task<IdentityUserDto> CreateAsync(IdentityUserCreateDto input) { // 执行原有的用户创建逻辑 var userDto = await base.CreateAsync(input); var user = await UserRepository.GetAsync(userDto.Id); if (!user.EmailConfirmed && !string.IsNullOrWhiteSpace(user.Email)) { // 生成确认令牌并发送邮件 var token = await _emailConfirmationService.GenerateConfirmationTokenAsync(user); var confirmationLink = $"https://your-angular-domain/account/confirm-email?userId={user.Id}&token={Uri.EscapeDataString(token)}&tenantId={_currentTenant.Id}"; await _emailSender.SendAsync( to: user.Email, subject: "请确认你的邮箱", body: $"请点击以下链接完成邮箱确认:<a href=\"{confirmationLink}\">确认邮箱</a>", isBodyHtml: true ); } return userDto; } }
- 替换默认服务
在应用模块的ConfigureServices方法中,替换原有的IdentityUserAppService:
context.Services.Replace(ServiceDescriptor.Transient<IIdentityUserAppService, CustomIdentityUserAppService>());
关键注意事项
- 确保已在
appsettings.json中正确配置SMTP服务参数,示例如下:
"Settings": { "Abp.Mailing": { "Smtp": { "Host": "smtp.your-domain.com", "Port": 587, "UserName": "your-account@your-domain.com", "Password": "your-password", "EnableSsl": true } } }
- 将代码中的
https://your-angular-domain替换为实际的Angular应用域名,同时确保前端确认页面能正确接收userId、token参数,并调用ABP的邮箱确认API完成验证。
内容的提问来源于stack exchange,提问作者Jerry
相关产品推荐
相关产品推荐

