一 Abp.Zero 手機號免密登錄驗證與號碼綁定功能的實現:驗證碼模塊

這是一篇系列博文 , 我將使用Abp.Zero搭建一套集成手機號免密登錄驗證與號碼綁定功能的用戶系統:

  • Abp.Zero 手機號免密登錄驗證與號碼綁定功能的實現(一):驗證碼模塊
  • Abp.Zero 手機號免密登錄驗證與號碼綁定功能的實現(二):改造Abp默認實現
  • Abp.Zero 手機號免密登錄驗證與號碼綁定功能的實現(三):網頁端開發
第三方身份驗證在Abp中稱之為外部身份驗證(ExternalAuthentication), 區別于Abp的外部身份授權(ExternalAuth),這里Auth的全稱應為Authorization,即授權 。
首先來厘清這兩個不同的業務在Abp中的實現,我之前寫的這篇 Abp.Zero 搭建第三方登錄模塊 系列文章中描述的業務,即使用的Abp外部身份授權(ExternalAuth)的相關擴展而實現的 。還記得我們實現的WeChatAuthProvider嗎?它繼承于ExternalAuthProviderApi這個抽象類,實現的微信授權功能 。所以微信登錄這個動作,實際是在授權(Authorization)已有的微信賬號,訪問服務端資源,而身份驗證(Authentication)步驟,已在其他端完成了(手機微信掃碼) , 在服務端獲取已驗證好身份的第三方賬戶并生成Token則可以抽象的認為是授權(Authorization)行為 。
所以“搭建第三方登錄模塊”應該更準確地描述為“第三方授權模塊” 。
從Abp接口設計上 , 也能看得出來兩者的差別 。
外部身份驗證(ExternalAuthentication)關注的是校驗 , 實現TryAuthenticateAsync并返回是否成功,而CreateUserAsync和UpdateUserAsync僅是校驗流程里的一部分,不實現它并不影響身份驗證結果 , 外部授權源的接口定義如下,
public interface IExternalAuthenticationSource<TTenant, TUser> where TTenant : AbpTenant<TUser> where TUser : AbpUserBase{...Task<bool> TryAuthenticateAsync(string userNameOrEmailAddress, string plainPassword, TTenant tenant);Task<TUser> CreateUserAsync(string userNameOrEmailAddress, TTenant tenant);Task UpdateUserAsync(TUser user, TTenant tenant);}外部授權(ExternalAuth)這一步關注的業務是拿到外部賬號,如微信的OpenId,所以IExternalAuthManager重點則是GetUserInfo,而IsValidUser并沒有在默認實現中使用到
public interface IExternalAuthManager{Task<bool> IsValidUser(string provider, string providerKey, string providerAccessCode);Task<ExternalAuthUserInfo> GetUserInfo(string provider, string accessCode);}然而這些是從LoginManager原本實現看出的,我們可以重寫這個類原本的方法 , 加入電話號碼的處理邏輯 。
在搞清楚這兩個接口后,相信你會對Abp用戶系統的理解更加深刻
短信獲取驗證碼來校驗,是比較常用的第三方身份驗證方式,今天來做一個手機號碼免密登錄,并且具有綁定/解綁手機號功能的小案例,效果如圖:
一 Abp.Zero 手機號免密登錄驗證與號碼綁定功能的實現:驗證碼模塊

文章插圖
示例代碼已經放在了GitHub上:Github:matoapp-samples
用戶驗證碼校驗模塊首先定義DomainService接口 , 我們將實現手機驗證碼的發送、驗證碼校驗、解綁手機號、綁定手機號
這4個功能,并且定義用途以校驗行為合法性,和用它來區分短信模板
public interface ICaptchaManager{Task BindAsync(string token);Task UnbindAsync(string token);Task SendCaptchaAsync(long userId, string phoneNumber, string purpose);Task<bool> VerifyCaptchaAsync(string token, string purpose = "IDENTITY_VERIFICATION");}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緩存管理類,以及對應的緩存條目類,用于承載驗證碼的校驗內容
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

推薦閱讀