public const string LOGIN = "LOGIN";public const string IDENTITY_VERIFICATION = "IDENTITY_VERIFICATION";public const string BIND_PHONENUMBER = "BIND_PHONENUMBER";public const string UNBIND_PHONENUMBER = "UNBIND_PHONENUMBER";
定义一个验证码Token缓存管理类 , 以及对应的缓存条目类 , 用于承载验证码的校验内容
【一 Abp.Zero 手机号免密登录验证与号码绑定功能的实现:验证码模块】public class SmsCaptchaTokenCache : MemoryCacheBase<SmsCaptchaTokenCacheItem>, ISingletonDependency{public SmsCaptchaTokenCache() : base(nameof(SmsCaptchaTokenCache)){}}
缓存条目将存储电话号码 , 用户Id(非登录用途)以及用途
public class SmsCaptchaTokenCacheItem{public string PhoneNumber { get; set; }public long UserId { get; set; }public string Purpose { get; set; }}
阿里云和腾讯云提供了短信服务Sms , 是国内比较常见的短信服务提供商 , 不需要自己写了 , 网上有大把的封装好的库 , 这里使用AbpBoilerplate.Sms作为短信服务库 。
创建短信验证码的领域服务类SmsCaptchaManager并实现ICaptchaManager接口 , 同时注入短信服务ISmsService , 用户管理服务UserManager , 验证码Token缓存管理服务SmsCaptchaTokenCache
public class SmsCaptchaManager : DomainService, ICaptchaManager{private readonly ISmsService SmsService;private readonly UserManager _userManager;private readonly SmsCaptchaTokenCache captchaTokenCache;public static TimeSpan TokenCacheDuration = TimeSpan.FromMinutes(5);public SmsCaptchaManager(ISmsService SmsService,UserManager userManager,SmsCaptchaTokenCache captchaTokenCache){this.SmsService=SmsService;_userManager=userManager;this.captchaTokenCache=captchaTokenCache;}}
新建SendCaptchaAsync方法 , 作为短信发送和缓存Token方法 , CommonHelp中的GetRandomCaptchaNumber()用于生成随机6位验证码 , 发送完毕后 , 将此验证码作为缓存条目的Key值存入
public async Task SendCaptchaAsync(long userId, string phoneNumber, string purpose){var captcha = CommonHelper.GetRandomCaptchaNumber();var model = new SendSmsRequest();model.PhoneNumbers= phoneNumber;model.SignName="MatoApp";model.TemplateCode= purpose switch{CaptchaPurpose.BIND_PHONENUMBER => "SMS_255330989",CaptchaPurpose.UNBIND_PHONENUMBER => "SMS_255330923",CaptchaPurpose.LOGIN => "SMS_255330901",CaptchaPurpose.IDENTITY_VERIFICATION => "SMS_255330974"};model.TemplateParam= JsonConvert.SerializeObject(new { code = captcha });var result = await SmsService.SendSmsAsync(model);if (string.IsNullOrEmpty(result.BizId) && result.Code!="OK"){throw new UserFriendlyException("验证码发送失败 , 错误信息:"+result.Message);}await captchaTokenCache.SetAsync(captcha, new SmsCaptchaTokenCacheItem(){PhoneNumber=phoneNumber,UserId=userId,Purpose=purpose}, absoluteExpireTime: DateTimeOffset.Now.Add(TokenCacheDuration));}
绑定手机号功能实现
public async Task BindAsync(string token){SmsCaptchaTokenCacheItem currentItem = await GetToken(token);if (currentItem==null || currentItem.Purpose!=CaptchaPurpose.BIND_PHONENUMBER){throw new UserFriendlyException("验证码不正确或已过期");}var user = await _userManager.GetUserByIdAsync(currentItem.UserId);if (user.IsPhoneNumberConfirmed){throw new UserFriendlyException("已绑定手机 , 请先解绑后再绑定");}user.PhoneNumber=currentItem.PhoneNumber;user.IsPhoneNumberConfirmed=true;await _userManager.UpdateAsync(user);await RemoveToken(token);}
解绑手机号功能实现
public async Task UnbindAsync(string token){SmsCaptchaTokenCacheItem currentItem = await GetToken(token);if (currentItem==null|| currentItem.Purpose!=CaptchaPurpose.UNBIND_PHONENUMBER){throw new UserFriendlyException("验证码不正确或已过期");}var user = await _userManager.GetUserByIdAsync(currentItem.UserId);user.IsPhoneNumberConfirmed=false;await _userManager.UpdateAsync(user);await RemoveToken(token);}
经验总结扩展阅读
- 2023年9月19日拜观音求子吉日一览表 2023年9月19日拜观音求子好吗
- 2023年9月19日上香吉日一览表 2023年9月19日上香好吗
- 2023年农历八月初五宜烧香吗 2023年9月19日烧香吉日一览表
- 2023年9月19日酬神吉日一览表 2023年9月19日适合酬神吗
- 2022双十一的节日祝福语 2022双十一的朋友圈祝福语
- 2022双十一的祝福语 双十一的微信祝福语
- 2023年9月19日祀灶吉日一览表 2023年9月19日是祀灶的黄道吉日吗
- 2023年农历八月初五修建坟墓吉日 2023年9月19日修建坟墓吉日一览表
- 2023年9月19日修路好吗 2023年9月19日修路吉日一览表
- 2023年9月19日出殡吉日一览表 2023年农历八月初五出殡吉日