标签:vNext SMSGrantType 短信 验证码 UserManager ABP context 生成 public
今天,准备在ABP vNext上拓展一下短信登录,流程很简单:用户请求发送验证码接口,后台生成验证码,然后发送到用户手机,用户收到验证码,使用拓展授权方式SMSGrantType获取令牌,完成授权。
首先,关于验证码生成,为了避免生成存储到本地再校验一般采用TOTP加密算法,它是基于时间的一次性密码生成算法,由 RFC 6238 定义。和基于事件的一次性密码生成算法不同 HOTP,TOTP 是基于时间的,在有效时间过后,针对同一用户所生成的验证码将会发生改变。
AspNetCore已经在其TOTP- (2FA) 双因素身份验证 里借助Rfc6238AuthenticationService实现了加密,我去翻了一遍源码,大概调用流程如下:
然后,我们可以借助这个加密算法来进行短信验证码生成,通过拓展IDS4的grant_type来做一个SMSGrantType的授权方式。
第一步,生成验证码
1 public class SmsService : ApplicationService, ISmsService 2 { 3 private readonly UserManager<Volo.Abp.Identity.IdentityUser> UserManager; 4 public SmsService( 5 IdentityUserManager identityUserManager, 6 UserManager<Volo.Abp.Identity.IdentityUser> userManager) 7 { 8 UserManager = userManager; 9 } 10 } 11 12 // 生成验证码 13 protected async Task<string> GetVerificationCodeAsync( 14 Volo.Abp.Identity.IdentityUser user, string selectedProvider = "Phone") 15 { 16 var code = await UserManager.GenerateTwoFactorTokenAsync(user, selectedProvider); 17 18 Check.NotNull(code, nameof(code)); 19 20 return code; 21 } 22 }
第二步,HttpApi.Host 层拓展自定义授权模式
1 public class ExtensionGrantTypes 2 { 3 public const string SMSGrantType = "SMSGrantType"; 4 } 5 6 public class SMSGrantValidator : IExtensionGrantValidator 7 { 8 public string GrantType => ExtensionGrantTypes.SMSGrantType; 9 private readonly UserManager<Volo.Abp.Identity.IdentityUser> UserManager; 10 private readonly IdentityUserManager IdentityUserManager; 11 12 public SMSGrantValidator( 13 UserManager<Volo.Abp.Identity.IdentityUser> userManager, 14 IdentityUserManager identityUserManager) 15 { 16 UserManager = userManager; 17 IdentityUserManager = identityUserManager; 18 } 19 20 public Task ValidateAsync(ExtensionGrantValidationContext context) 21 { 22 var smsCode = context.Request.Raw.Get("smsCode"); 23 var phoneNumber = context.Request.Raw.Get("phoneNumber"); 24 25 if (string.IsNullOrEmpty(smsCode) || string.IsNullOrEmpty(phoneNumber)) 26 { 27 context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant); 28 } 29 // 在此实现自己的验证逻辑… 30 return Task.FromResult(0); 31 } 32 }
第三步,XXXHttpApiHostModule注册校验类
1 // 在httpapi.host的module文件内添加自定义授权模式 2 public override void PreConfigureServices(ServiceConfigurationContext context) 3 { 4 context.Services.PreConfigure<IIdentityServerBuilder>( 5 builder => 6 { 7 // 添加自定义授权模式 8 builder.AddExtensionGrantValidator<SMSGrantValidator>(); 9 } 10 ); 11 }
第四步,Domain添加Client数据种子(同时DbMigrator的appsettings添加配置)
1 var testClientId = configurationSection["Test_App:ClientId"]; 2 if (!testClientId.IsNullOrWhiteSpace()) 3 { 4 await CreateClientAsync( 5 name: testClientId, 6 scopes: commonScopes, 7 grantTypes: new[] { "password", "client_credentials", ExtensionGrantTypes.SMSGrantType }, 8 secret: (configurationSection["Test_App:ClientSecret"] ?? "123456").Sha256() 9 ); 10 }
第五步,愉快的使用(测试号码是假的不要来骚扰我......[狗头].jpg)
标签:vNext,SMSGrantType,短信,验证码,UserManager,ABP,context,生成,public 来源: https://www.cnblogs.com/magicalconch/p/14044990.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。