循序漸進VUE+Element 前端應用開發(32)--- 手機短信動態碼登陸處理


在一些系統中,有時候用戶忘記密碼,可以通過向自己手機發送動態驗證碼的方式實現系統登錄功能。本篇隨筆介紹如何結合后端ABP框架的短信發送和緩存模塊的處理,實現手機短信動態碼登陸處理。

一般的登錄方式,分為普通賬號登錄,動態密碼登陸,掃描二維碼登錄等幾種方式,其他方式這里不講,主要介紹動態碼登錄方式。

1、短信驗證碼的發送處理 

 我在上篇隨筆《ABP框架中短信發送處理,包括阿里雲短信和普通短信商的短信發送集成》中介紹了如何使用ABP框架實現短信的發送處理,因此我們前后端通過短信的方式,可以實現動態密碼的登陸處理。

因此在授權登陸的控制器中,我們增加短信發送的接口注入使用,如下所示。

 

然后通過定義兩個接口,一個是發送動態驗證碼給用戶手機的接口,一個是根據用戶手機和動態驗證碼的方式進行登錄處理接口。

然后我們在這個驗證身份的控制器上增加兩個方法即可。

用例也就是分了兩個處理方法。

 

 在處理發送短信驗證碼之前,我們來介紹一下短信驗證碼的處理規則,我們發送短信成功后,把驗證碼存在系統緩存里面,一般系統緩存是存放在Redis里面,緩存需要一個鍵和定義好的類對象進行存儲。

我們定義好存儲的對象類,再在系統中使用即可。

    /// <summary>
    /// 短信登陸動態密碼緩存對象
    /// </summary>
    [Serializable]
    public class SmsLoginCodeCacheItem
    {
        public const string CacheName = "AppSmsLoginCodeCacheItem";

        public string Code { get; set; }

        public string PhoneNumber { get; set; }

        public SmsLoginCodeCacheItem()
        {
        }

        public SmsLoginCodeCacheItem(string code, string phone)
        {
            Code = code;
            PhoneNumber = phone;
        }
    }

我們可以在系統模塊初始化的時候,配置好緩存對應的失效時間,如下所示。

            //配置SMS登錄動態碼有效期限
            Configuration.Caching.Configure(SmsLoginCodeCacheItem.CacheName, cache =>
            {
                cache.DefaultSlidingExpireTime = TimeSpan.FromMinutes(Constants.SmsCodeExpiredMinutes);
            });

發送短信驗證碼作為動態密碼的邏輯代碼如下所示。

        /// <summary>
        /// 發送登錄動態碼
        /// </summary>
        /// <param name="model">手機登錄動態碼</param>
        /// <returns></returns>
        [HttpPost]
        public async Task<CommonResult> SendPhoneLoginSmsCode([FromBody] AuthenticateByPhoneCaptchaModel model)
        {
            //獲取隨機6位數字動態驗證碼
            var code = RandomHelper.GetRandom(100000, 999999).ToString();

            //使用自定義模板處理短信發送
            string message = string.Format(Constants.MySmsCodeTemplate, code);
            var result =  await _smsSender.SendAsync(model.PhoneNumber, message);
            if(result.Success)
            {
                var cacheKey = model.PhoneNumber;//以手機號碼作為鍵存儲驗證碼緩存
                var cacheItem = new SmsLoginCodeCacheItem { Code = code, PhoneNumber = model.PhoneNumber };

                var cache = _cacheManager.GetCache<string, SmsLoginCodeCacheItem>(SmsLoginCodeCacheItem.CacheName);
                cache.Set(cacheKey, cacheItem);
            }

            return result;
        }

我們還需要在前端中設計一個使用動態短信碼登錄的界面,如下所示。

短信發送成功,可以在用戶手機查看對應的動態碼。

 驗證碼發送后,我們也可以在Redis中看到對應的數據,如下所示。

 

2、動態碼登錄處理

發送了短信碼后,系統在緩存中存放一段時間的數據,如果在這個期間進行登錄,會根據緩存進行匹配,如果匹配成功,那么就進行相關登錄身份的處理即可。

系統登錄驗證的處理代碼如下所示。

        /// <summary>
        /// 通過手機驗證碼授權
        /// </summary>
        /// <param name="model">手機驗證碼Dto</param>
        /// <returns></returns>
        [HttpPost]
        public async Task<AuthenticateResultModel> AuthenticateByPhoneCaptcha([FromBody] AuthenticateByPhoneCaptchaModel model)
        {
            var loginResult = await GetLoginResultByPhoneCaptchaAsync(
                model.PhoneNumber,
                model.SmsCode,
                GetTenancyNameOrNull()
            );

            //if(loginResult.Result == AbpLoginResultType.Success)
            //這里成功,移除短信緩存
            var cache = _cacheManager.GetCache<string, SmsLoginCodeCacheItem>(SmsLoginCodeCacheItem.CacheName);
            cache.Remove(model.PhoneNumber);//移除緩存短信鍵值

            var accessToken = CreateAccessToken(CreateJwtClaims(loginResult.Identity));
            return new AuthenticateResultModel
            {
                AccessToken = accessToken,
                ExpireInSeconds = (int)_configuration.Expiration.TotalSeconds,
                EncryptedAccessToken = GetEncryptedAccessToken(accessToken),
                UserId = loginResult.User.Id
            };
        }

這里主要的邏輯封裝在 GetLoginResultByPhoneCaptchaAsync 中,這個登錄的方式可以參考ABP框架基礎的登陸方式進行改動即可。

        /// <summary>
        /// 獲取登陸結果通過手機驗證碼
        /// </summary>
        /// <param name="phoneNumber">手機號</param>
        /// <param name="captcha">驗證碼</param>
        /// <param name="tenancyName">租戶名</param>
        /// <returns></returns>
        private async Task<AbpLoginResult<Tenant, User>> GetLoginResultByPhoneCaptchaAsync(string phoneNumber, string captcha, string tenancyName)
        {
            var loginResult = await _logInManager.LoginByMobileAsync(phoneNumber, captcha, tenancyName);
            switch (loginResult.Result)
            {
                case AbpLoginResultType.Success:
                    return loginResult;
                default:
                    throw _abpLoginResultTypeHelper.CreateExceptionForFailedLoginAttempt(loginResult.Result, loginResult.User.UserName, tenancyName);
            }
        }

參照ABP框架基礎的登陸授權方式,我們在UserManager中增加類似的驗證碼登陸管理方式,如下所示。

前端在處理相關發送驗證碼和登錄授權的操作,是針對API的調用,因此需要封裝對應的API處理。

 

 然后仿照常規登錄的處理,編寫一個動態碼登錄的處理方式,放在對應的Module中即可。

  dynamiclogin({ commit }, userInfo) { // 動態密碼登陸
    const { mobile, smscode } = userInfo
    return new Promise((resolve, reject) => {
      tokenauth.AuthenticateByPhoneCaptcha({ phoneNumber: mobile.trim(), smsCode: smscode }).then(response => {
        const { result } = response // 獲取返回對象的 result
        // console.log(result)// 記錄數據
        var token = result.accessToken // 用戶令牌
        var userId = result.userId // 用戶id

        // 修改State對象,記錄令牌和用戶Id
        commit('SET_TOKEN', token)
        commit('SET_USERID', userId)
        // 存儲cookie
        setToken(token)
        setUserId(userId)

        resolve()
      }).catch(error => {
        reject(error)
      })
    })
  },

 

 在登錄界面中,輸入動態碼登錄即可順利進入系統,和常規的處理一樣。

 

 以上就是參照常規賬號密碼登錄的方式,構建一個動態碼登錄的處理,流程還是差不多,不過整合了短信發送,緩存處理,賬號登陸等幾個流程,可以作為一個簡單的系統登錄過程的了解。

 

為了方便讀者理解,我列出一下前面幾篇隨筆的連接,供參考:

循序漸進VUE+Element 前端應用開發(1)--- 開發環境的准備工作

循序漸進VUE+Element 前端應用開發(2)--- Vuex中的API、Store和View的使用

循序漸進VUE+Element 前端應用開發(3)--- 動態菜單和路由的關聯處理

循序漸進VUE+Element 前端應用開發(4)--- 獲取后端數據及產品信息頁面的處理

循序漸進VUE+Element 前端應用開發(5)--- 表格列表頁面的查詢,列表展示和字段轉義處理

循序漸進VUE+Element 前端應用開發(6)--- 常規Element 界面組件的使用

循序漸進VUE+Element 前端應用開發(7)--- 介紹一些常規的JS處理函數

循序漸進VUE+Element 前端應用開發(8)--- 樹列表組件的使用

循序漸進VUE+Element 前端應用開發(9)--- 界面語言國際化的處理

循序漸進VUE+Element 前端應用開發(10)--- 基於vue-echarts處理各種圖表展示 

循序漸進VUE+Element 前端應用開發(11)--- 圖標的維護和使用

循序漸進VUE+Element 前端應用開發(12)--- 整合ABP框架的前端登錄處理

循序漸進VUE+Element 前端應用開發(13)--- 前端API接口的封裝處理

循序漸進VUE+Element 前端應用開發(14)--- 根據ABP后端接口實現前端界面展示

循序漸進VUE+Element 前端應用開發(15)--- 用戶管理模塊的處理

循序漸進VUE+Element 前端應用開發(16)--- 組織機構和角色管理模塊的處理 

循序漸進VUE+Element 前端應用開發(17)--- 菜單管理

循序漸進VUE+Element 前端應用開發(18)--- 功能點管理及權限控制  

VUE+Element 前端應用開發框架功能介紹 

循序漸進VUE+Element 前端應用開發(19)--- 后端查詢接口和Vue前端的整合

使用代碼生成工具快速生成基於ABP框架的Vue+Element的前端界面

循序漸進VUE+Element 前端應用開發(20)--- 使用組件封裝簡化界面代碼

循序漸進VUE+Element 前端應用開發(21)--- 省市區縣聯動處理的組件使用

循序漸進VUE+Element 前端應用開發(22)--- 簡化main.js處理代碼,抽取過濾器、全局界面函數、組件注冊等處理邏輯到不同的文件中

循序漸進VUE+Element 前端應用開發(23)--- 基於ABP實現前后端的附件上傳,圖片或者附件展示管理 

循序漸進VUE+Element 前端應用開發(24)--- 修改密碼的前端界面和ABP后端設置處理

循序漸進VUE+Element 前端應用開發(25)--- 各種界面組件的使用(1)

循序漸進VUE+Element 前端應用開發(26)--- 各種界面組件的使用(2)

電商商品數據庫的設計和功能界面的處理 

循序漸進VUE+Element 前端應用開發(27)--- 數據表的動態表單設計和數據存儲

循序漸進VUE+Element 前端應用開發(28)--- 附件內容的管理 

循序漸進VUE+Element 前端應用開發(29)--- 高級查詢條件的界面設計

部署基於.netcore5.0的ABP框架后台Api服務端,以及使用Nginx部署Vue+Element前端應用

循序漸進VUE+Element 前端應用開發(30)--- ABP后端和Vue+Element前端結合的分頁排序處理 

循序漸進VUE+Element 前端應用開發(31)--- 系統的日志管理,包括登錄日志、接口訪問日志、實體變化歷史日志

循序漸進VUE+Element 前端應用開發(32)--- 手機短信動態碼登陸處理 

循序漸進VUE+Element 前端應用開發(33)--- 郵件參數配置和模板郵件發送處理 

使用代碼生成工具快速開發ABP框架項目 

使用Vue-TreeSelect組件實現公司-部門-人員級聯下拉列表的處理 

使用Vue-TreeSelect組件的時候,用watch變量方式解決彈出編輯對話框界面無法觸發更新的問題 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM