51.【.NET8 实战--孢子记账--从单体到微服务--转向微服务】--新增功能--登录注册扩展

在这篇文章中我们将为登录和注册的功能增加邮箱和手机号码。通过添加这些额外的验证方式,我们可以为用户提供更多的账号安全保障,同时也能让用户在忘记密码时有多种找回方式。邮箱验证将支持通过发送验证码来确认用户身份,而手机号码则可以通过短信验证的方式来进行双重认证。这些功能的加入不仅提升了系统的安全性,也为用户带来了更好的使用体验。我们将详细介绍如何在现有的登录注册系统中集成这些新特性,包括数据库设计的调整、API接口的扩展以及相关服务的实现。

Tip:发送手机验证码功能我们将在后续文章中讲解

一、修改数据库

我们先修改数据库,修改方式也很简单,打开数据库上下文类IdentityServerDbContext,将OnModelCreating方法中的b.Ignore(x => x.PhoneNumberConfirmed);删除掉,修改后的代码如下:

csharp 复制代码
/// <summary>
/// 配置数据库模型
/// </summary>
/// <param name="modelBuilder"></param>
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);
    // 配置 OpenIddict
    modelBuilder.UseOpenIddict();
    // 修改Users表
    modelBuilder.Entity<SpUser>(b =>
    {
        b.Property(x => x.UserName).IsRequired().HasMaxLength(50);
        b.Property(x => x.Email).HasMaxLength(100);
        b.Property(x => x.LockoutEnd);
        b.Property(x => x.PasswordHash).IsRequired();
        b.Ignore(x => x.NormalizedUserName);
        b.Ignore(x => x.NormalizedEmail);
        b.Ignore(x => x.SecurityStamp);
        b.Ignore(x => x.ConcurrencyStamp);
        b.Ignore(x => x.TwoFactorEnabled);
        b.Ignore(x => x.AccessFailedCount);
    });
    SeedData(modelBuilder);
}

在我们之前的文章24.【.NET8 实战--孢子记账--从单体到微服务--转向微服务】--单体转微服务--认证微服务中,我们详细讲解了OnModelCreating方法的配置原理和具体实现。这个方法主要负责配置实体模型与数据库表之间的映射关系,包括字段的长度限制、必填项设置等重要配置。完成OnModelCreating方法的修改后,我们需要通过Entity Framework Core的迁移功能来将这些更改同步到数据库中。这个过程需要执行两个重要的命令:首先使用dotnet ef migrations add AddPhoneNumberConfirmed --context IdentityServerDbContext创建一个新的迁移文件,该文件包含了所有需要对数据库进行的修改操作;然后通过dotnet ef database update AddPhoneNumberConfirmed命令将这些修改实际应用到数据库中。这样,我们就完成了数据库结构的更新,为后续功能的开发做好了基础准备。

二、修改接口

接下来,我们需要对系统的接口层进行必要的修改和扩展,以支持新增的登录验证方式。本次修改主要涉及三个核心接口:用于处理登录认证的POST token接口、处理新用户注册的POST register接口,以及用于更新用户信息的PUT users接口。让我们以POST token接口的改造为重点,详细说明实现过程。

首先,我们需要打开认证服务的核心实现类AuthorizationServiceImpl。在这个类中,我们将重点关注LoginByPasswordAsync方法的实现。原本的代码仅支持通过用户名查找用户,现在我们需要将其扩展为支持多种登录方式。具体来说,我们需要将原来的单一查询语句SpUser? user = await _userManager.FindByNameAsync(userName);进行改造。这行代码最初的设计仅支持通过用户名进行身份验证,这显然无法满足我们对多渠道登录的需求。通过修改这段代码,我们将实现一个更加灵活和用户友好的登录系统,让用户可以选择使用自己最熟悉的方式进行身份验证。

csharp 复制代码
SpUser? user =await _userManager.Users.FirstOrDefaultAsync(u =>
        u.PhoneNumber == userName || u.Email == userName || u.UserName == userName);

这部分代码实现了一个灵活的用户查找机制,通过使用传入的参数作为查询条件,同时匹配用户的手机号、邮箱和用户名三个字段。这种多字段匹配的设计让用户可以使用任意一种已注册的身份标识(手机号、邮箱或用户名)进行登录,大大提升了系统的用户友好性。当用户输入任意一个有效的身份标识时,系统会在数据库中搜索所有可能的匹配项,只要找到一个符合条件的用户记录,就表示该账号在系统中存在并可以进行后续的身份验证流程。

三、总结

这篇文章详细介绍了如何扩展现有的登录注册系统,通过添加邮箱和手机号码验证功能来增强用户账号的安全性和便利性。我们首先对数据库结构进行了必要的调整,启用了手机号码验证功能;然后扩展了认证接口,使系统能够支持用户通过多种方式(用户名、邮箱或手机号)进行登录。这些改进不仅提升了系统的安全性,也为用户提供了更加灵活和友好的使用体验。通过这些优化,我们的系统更好地满足了现代应用对用户认证的多样化需求。

相关推荐
2301_803875611 小时前
PHP 中处理会话数组时的类型错误解析与修复指南
jvm·数据库·python
m0_743623921 小时前
c++如何批量修改文件后缀名_std--filesystem--replace_extension【实战】
jvm·数据库·python
rockey6272 小时前
AScript函数体系详解
c#·.net·script·eval·expression·function·动态脚本
2501_914245932 小时前
CSS如何处理CSS变量作用域冲突_利用特定类名重写变量值
jvm·数据库·python
maqr_1103 小时前
MySQL数据库迁移到云端如何保障安全_数据加密与SSL连接配置
jvm·数据库·python
u0109147603 小时前
MySQL如何限制触发器递归调用的深度_防止触发器死循环方法
jvm·数据库·python
weixin_381288183 小时前
MySQL中如何使用HEX函数转换十六进制_MySQL进制转换函数
jvm·数据库·python
Deitymoon4 小时前
嵌入式数据库——SQLite基础
数据库·sqlite
YMatrix 官方技术社区4 小时前
美国·硅谷|YMatrix 即将亮相 Postgres Conference 2026,前瞻 AI 时代的数据基座
数据库·数据仓库·postgresql·时序数据库·ymatrix
bKYP953cL4 小时前
构建自己的AI编程助手:基于RAG的上下文感知实现方案
数据库·人工智能·ai编程