ABP vNext 拓展短信授权登陆

ASP.NET Core实现短信验证码登录:TOTP加密与自定义授权
本文介绍了如何在ABPvNext平台上通过TOTP算法生成短信验证码,并扩展IdentityServer实现SMSGrantType授权,详细步骤包括验证码生成、自定义授权验证和模块配置。

今天,准备在ABP vNext上拓展一下短信登录,流程很简单:用户请求发送验证码接口,后台生成验证码,然后发送到用户手机,用户收到验证码,使用拓展授权方式SMSGrantType获取令牌,完成授权。

首先,关于验证码生成,为了避免生成存储到本地再校验一般采用TOTP加密算法,它是基于时间的一次性密码生成算法,由 RFC 6238 定义。和基于事件的一次性密码生成算法不同 HOTP,TOTP 是基于时间的,在有效时间过后,针对同一用户所生成的验证码将会发生改变。

AspNetCore已经在其TOTP- (2FA) 双因素身份验证 里借助Rfc6238AuthenticationService实现了加密,我去翻了一遍源码,大概调用流程如下:

实现原理 => 加密实现 => 加密调用 => 认证调用 => 使用示例

然后,我们可以借助这个加密算法来进行短信验证码生成,通过拓展IDS4的grant_type来做一个SMSGrantType的授权方式。

第一步,生成验证码

<think>我们正在使用ABP vNext框架,并希望扩展AbpUsers表以添加新字段。根据引用[2]和引用[3]的内容,我们可以通过以下步骤实现:1.**创建扩展类**:创建一个新的类(例如`AppUser`)来定义要添加的字段。这个类不需要继承任何父类,但需要使用数据注解(如`[MaxLength]`)来配置字段属性。 2. **配置对象扩展**:在模块类(通常是`YourProjectNameModule`)的`ConfigureServices`方法中,使用`ObjectExtensionManager`来扩展`IdentityUser`实体(因为AbpUsers表对应的是`IdentityUser`实体)。 3. **更新数据库**:添加迁移并更新数据库,使新字段在数据库中生效。 详细步骤如下: ###步骤1:创建扩展类在领域层(通常是`Domain`项目)中创建一个类,例如`AppUser`,用于定义新增字段。注意,这个类不需要继承任何基类。 ```csharppublicclass AppUser{[MaxLength(50)]publicstring MemberCode {get;set;}//添加其他字段...public int? Age{ get; set; }//示例:添加一个地址字段,长度限制为200[MaxLength(200)]publicstring Address{ get; set; }} ```###步骤2:配置对象扩展在模块类(通常是`YourProjectNameDomainModule`)的`ConfigureServices`方法中,添加以下代码:```csharppublic overridevoid ConfigureServices(ServiceConfigurationContext context) {Configure<AbpIdentityOptions>(options =>{options.ConfigureObjectExtensions= objConfig=>{//扩展IdentityUser实体objConfig.MapEfCoreProperty<IdentityUser, string>("MemberCode",(entityBuilder, propertyBuilder)=>{propertyBuilder.HasMaxLength(50);});objConfig.MapEfCoreProperty<IdentityUser,int?>("Age");objConfig.MapEfCoreProperty<IdentityUser,string>("Address",(entityBuilder, propertyBuilder)=>{propertyBuilder.HasMaxLength(200);});};});} ```或者,使用ABP提供的扩展方法简化:```csharppublic overridevoid ConfigureServices(ServiceConfigurationContext context) {ObjectExtensionManager.Instance.AddOrUpdateProperty<IdentityUser,string>("MemberCode", options=>{options.MapEfCore(b=> b.HasMaxLength(50));}).AddOrUpdateProperty<IdentityUser,int?>("Age").AddOrUpdateProperty<IdentityUser, string>("Address", options=>{options.MapEfCore(b=> b.HasMaxLength(200));});} ```###步骤3:更新数据库1.在`EntityFrameworkCore`项目(例如`YourProjectName.EntityFrameworkCore`)中,打开`DbContext`(通常是`YourProjectNameDbContext`)并在`OnModelCreating`方法中添加以下代码:```csharpprotected overridevoid OnModelCreating(ModelBuilderbuilder){base.OnModelCreating(builder);//配置扩展属性builder.Entity<IdentityUser>(b=>{b.Property<string>("MemberCode").HasMaxLength(50);b.Property<int?>("Age");b.Property<string>("Address").HasMaxLength(200);}); }``` 2.打开程序包管理器控制台,选择`EntityFrameworkCore`项目作为默认项目,然后执行以下命令:```bashAdd-Migration"Added_User_Extra_Fields"Update-Database``` 这样,新字段就会添加到AbpUsers表中。###注意事项-如果使用领域驱动设计(DDD),可以在领域层定义这些属性,并在应用层和界面层使用它们。-在应用层和界面层,可以通过`IdentityUserDto`的扩展属性来使用这些新字段(需要扩展DTO)。 ###扩展DTO为了在API和UI中使用新字段,还需要扩展`IdentityUserDto`:1.在应用层(`Application`项目)中,创建一个新的类`IdentityUserDtoExtensions`:```csharppublic staticclass IdentityUserDtoExtensions{public staticIdentityUserDto MapExtraProperties(this IdentityUserDtouserDto, IdentityUser user){//将扩展属性从实体映射到DTOuserDto.SetProperty("MemberCode", user.GetProperty<string>("MemberCode"));userDto.SetProperty("Age", user.GetProperty<int?>("Age"));userDto.SetProperty("Address", user.GetProperty<string>("Address"));returnuserDto;} }``` 2.在`IdentityUserAppService`中重写`MapIdentityUserToDto`方法(或使用AutoMapper配置),将扩展属性映射到DTO。 以上就是在ABPvNext中扩展AbpUsers实体以添加新字段的方法。§§相关问题§§1.如何扩展ABPvNext中的其他默认实体(如角色、组织单位)? 2.在ABP vNext中,如何为扩展的字段添加验证规则? 3.如何在前端(如Angular或Vue)中显示和使用扩展的字段?</think>### 在ABP vNext中扩展AbpUsers实体添加新字段 在ABP vNext中扩展默认实体(如`AbpUsers`)添加新字段,需遵循**领域驱动设计(DDD)**原则,通过**对象扩展系统**实现非侵入式扩展。以下是详细步骤: #### 步骤1:创建扩展类(领域层) 在`Domain`项目中创建用户扩展类(无需继承): ```csharp // Domain/Extensions/AppUserExtraProperties.cs public class AppUserExtraProperties { [MaxLength(100)] public string WeChatId { get; set; } // 示例:添加微信ID字段 public DateTime? Birthday { get; set; } // 示例:添加生日字段 [Range(0, 100)] public int? SecurityLevel { get; set; } // 示例:安全等级字段 } ``` > 说明:使用数据注解`[MaxLength]`、`[Range]`定义字段约束[^3]。 #### 步骤2:注册实体扩展(模块配置) 在领域模块的`ConfigureServices`中注册扩展: ```csharp // YourProjectNameDomainModule.cs public override void ConfigureServices(ServiceConfigurationContext context) { ObjectExtensionManager.Instance .AddOrUpdate<IdentityUser>(options => { options.AddOrUpdateProperty<AppUserExtraProperties>(x => x.WeChatId); options.AddOrUpdateProperty<AppUserExtraProperties>(x => x.Birthday); options.AddOrUpdateProperty<AppUserExtraProperties>(x => x.SecurityLevel); }); } ``` > 关键点:使用`ObjectExtensionManager`动态扩展`IdentityUser`实体(对应AbpUsers表)[^1]。 #### 步骤3:更新数据库(EF Core层) 1. **添加EF Core映射**(在`EntityFrameworkCore`项目): ```csharp // YourProjectNameDbContextModelCreatingExtensions.cs builder.Entity<IdentityUser>(b => { b.Property<string>("WeChatId").HasMaxLength(100); b.Property<DateTime?>("Birthday"); b.Property<int?>("SecurityLevel"); }); ``` 2. **生成数据库迁移**: ```bash dotnet ef migrations add Added_User_ExtraFields dotnet ef database update ``` #### 步骤4:扩展DTO(应用层) 在`Application`项目中扩展用户DTO: ```csharp // Application/Users/IdentityUserDto.cs public class IdentityUserDtoExt : IdentityUserDto { public string WeChatId { get; set; } public DateTime? Birthday { get; set; } public int? SecurityLevel { get; set; } } ``` #### 步骤5:更新AutoMapper配置 ```csharp // Application/AutoMapper/YourProjectNameApplicationAutoMapperProfile.cs CreateMap<IdentityUser, IdentityUserDtoExt>() .MapExtraProperties(); // 自动映射扩展属性 ``` #### 验证扩展结果 - **数据库**:AbpUsers表将新增`WeChatId`、`Birthday`、`SecurityLevel`字段 - **API**:用户查询接口返回的DTO包含扩展字段 - **验证**:自动应用数据注解规则(如长度、范围验证) ### 核心优势 1. **零修改核心代码**:符合开闭原则,不修改ABP框架源码[^1] 2. **动态扩展**:通过`ObjectExtensionManager`统一管理扩展属性 3. **自动映射**:`MapExtraProperties()`简化DTO映射 4. **完整集成**:扩展字段自动参与数据库迁移、验证、API序列化 > 注意:扩展字段在EF Core中存储为**表列**而非JSON字段,确保查询效率[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值