基於SqlSugar的開發框架循序漸進介紹(17)-- 基於CSRedis實現快取的處理

2022-10-28 12:01:35

在一個應用系統的開發框架中,往往很多地方需要用到快取的處理,有些地方是為了便於記錄使用者的資料,有些地方是為了提高系統的響應速度,如有時候我們在傳送一個簡訊驗證碼的時候,可以在快取中設定幾分鐘的過期時間,這樣驗證簡訊驗證碼的時候,就會自動判斷是否過期了。本篇隨筆結合CSRedis的使用,介紹如何實現快取的初始化及使用的處理。

1、在基於.netCore的Web API後端使用CSRedis

關於CSRedis的使用,我們可以參考Github網站:https://github.com/2881099/csredis  進行了解。

首先我們在使用前,需要新增對應的程式集應用。

Package NameNuGetDownloads 
CSRedisCore

 初始化CSRedis也比較簡單,如程式碼所示。

var csredis = new CSRedis.CSRedisClient("127.0.0.1:6379,password=123,defaultDatabase=13,prefix=my_");

不過我們的Redis設定一般放在appSettings.json檔案中,不是直接寫死的,所以需要調整一下。

//初始化Redis及分散式快取
var redisConnectionString = builder.Configuration["CSRedis:ConnectString"];
RedisHelper.Initialization(new CSRedisClient(redisConnectionString));
builder.Services.AddSingleton<IDistributedCache>(new CSRedisCache(RedisHelper.Instance));

常規的快取設定,通過鍵、值、時間設定等幾個內容進行處理,如下程式碼所示。

RedisHelper.Set("test1", "123123", 60);

RedisHelper.Get("test1");

如果我們要清空所有的快取鍵值,那麼對鍵進行模式匹配進行處理即可。

/// <summary>
/// 清空Redis快取
/// </summary>
protected void ClearRedisCache()
{
    //查詢所有分割區節點中符合給定模式(pattern)的 key
    var cacheKeys = RedisHelper.Keys("*");
    RedisHelper.Del(cacheKeys);
}

除了常規的快取處理,redis也支援訊息佇列的處理,訊息佇列最熟悉無疑是 rabbitmq,它基本是業界標準的解決方案。另外 redis 也提供了多種實現輕訂閱方法。如下面是一案例程式碼。

//程式1:使用程式碼實現訂閱端
var sub = RedisHelper.Subscribe(("chan1", msg => Console.WriteLine(msg.Body)));
//sub.Disponse(); //停止訂閱

//程式2:使用程式碼實現釋出端
RedisHelper.Publish("chan1", "111");

我們這裡不深究訊息佇列的處理,有興趣的可以參考文章《【由淺至深】redis 實現釋出訂閱的幾種方式》進行了解即可。

 

2、前端傳送簡訊驗證碼及後端判斷

我們這裡以一個簡訊驗證碼登入的前端來介紹CSRedis快取的設定、獲取、移除等操作過程。

例如,我們的移動前端,需要驗證碼登入系統的時候,需要傳送驗證碼的操作,如下所示。

前端通過初步判斷手機號碼正確後,可以向後端請求傳送驗證碼,如下邏輯程式碼所示(vue)

// 獲取驗證碼
getCode() {
    if (this.model.mobile.length < 11 && !uni.$u.test.mobile(this.model.mobile)) {
        uni.$u.toast('手機號碼不正確')
        return;
    }

    //傳送簡訊驗證碼
    var params = {
        PhoneNumber: this.model.mobile
    }
    user.SendPhoneLoginSmsCode(params).then(res => {
        if (res.success) {
            this.show = false;
            uni.$u.toast(`驗證碼已傳送至手機 ${this.model.mobile},請注意查收!`)

            let interval = setInterval(() => {
                this.second--;
                if (this.second <= 0) {
                    this.show = true;
                    clearInterval(interval);
                }
            }, 1000);
        } else {
            uni.$u.toast('傳送出現錯誤:' + res.errorMessage)
        }
    })
}

WebAPI後端,處理邏輯是構建隨機的驗證碼並通過簡訊傳送到手機上,並快取好對應的驗證碼,後端的處理程式碼如下所示

/// <summary>
/// 傳送登入動態碼
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
[AllowAnonymous]
[HttpPost]
[Route("send-login-smscode")]
public async Task<CommonResult> SendPhoneLoginSmsCode(PhoneCaptchaModel model)
{
    //獲取隨機6位數位動態驗證碼
    var code = RandomChinese.GetRandomNumber(6);

    //使用自定義模板處理簡訊傳送
    string message = string.Format(ConfigData.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 };

        RedisHelper.Set(cacheKey, cacheItem, TimeSpan.FromMinutes(ConfigData.SmsCodeExpiredMinutes));

        //獲取的時候
        //var tmp = RedisHelper.Get<SmsLoginCodeCacheItem>(cacheKey);
    }

    return result;
}

順利傳送簡訊驗證碼後,前端會提示使用者驗證碼傳送情況,並要求輸入驗證碼進行登入,前端登入的程式碼如下所示。

//簡訊驗證碼登入
loginByCode() {
    var params = {
        mobile: this.model.mobile,
        smscode: this.model.code
    };
    console.log(params);
    user.dynamiclogin(params)
        .then(res => {
            uni.$u.toast('驗證成功');

            this.gotoPage();
        })
        .catch(error => {
            console.log('驗證失敗' + error);
            uni.$u.toast(error);
        });
},

後端的登入處理,主要就是通過在Redis中讀取對應的手機驗證碼,如果匹配進行令牌的生成處理,否則提示錯誤資訊。

/// <summary>
/// 登入授權處理
/// </summary>
/// <returns></returns>
[AllowAnonymous]
[HttpPost]
[Route("authenticate-byphone")]
public async Task<AuthenticateResultDto> AuthenticateByPhoneCaptcha(PhoneCaptchaModel model)
{
    var authResult = new AuthenticateResultDto();
    #region 條件檢查
    if (string.IsNullOrEmpty(model.PhoneNumber))
    {
        throw new MyApiException("手機號不能為空");
    }
    if (string.IsNullOrEmpty(model.SmsCode))
    {
        throw new MyApiException("驗證碼不能為空");
    }

    var userInfo = await _userService.GetFirstAsync(s => s.MobilePhone == model.PhoneNumber);
    if (userInfo == null)
    {
        throw new MyApiException("使用者手機不存在");
    }
    #endregion

    var cacheKey = model.PhoneNumber;//以手機號碼作為鍵儲存驗證碼快取
    var item = RedisHelper.Get<SmsLoginCodeCacheItem>(cacheKey);
    if (item != null && item.Code == model.SmsCode)
    {
        //根據使用者身份生成tokenresult
        authResult.AccessToken = GenerateToken(userInfo); //令牌
        authResult.Expires = expiredDays * 24 * 3600; //失效秒數
        authResult.Success = true;//成功
        authResult.UserId = userInfo.Id;//當前使用者Id

        //移除快取簡訊鍵值
        RedisHelper.Del(cacheKey);
    }
    else
    {
        authResult.Error = "登入失敗,無法生成令牌";
    }
    return authResult;
}

如果順利生成令牌,則從redis中移除對應的快取鍵值即可。

如果我們需要檢視Redis的快取內容,Windows端可以安裝 RedisDesktopManager 進行檢視管理Redis的內容。

傳送簡訊後,鍵值會儲存在Redis快取中,可以通過RedisDesktopManager  進行檢視。

手機端順利收到簡訊提示。

 

 

以上就是關於在SqlSugar的開發框架,通過介紹簡訊驗證碼的前後端共同作業方式,介紹使用CSRedis實現快取的處理過程。

 

系列文章:

基於SqlSugar的開發框架的循序漸進介紹(1)--框架基礎類的設計和使用

基於SqlSugar的開發框架循序漸進介紹(2)-- 基於中間表的查詢處理

基於SqlSugar的開發框架循序漸進介紹(3)-- 實現程式碼生成工具Database2Sharp的整合開發

基於SqlSugar的開發框架循序漸進介紹(4)-- 在資料存取基礎類別中對GUID主鍵進行自動賦值處理 

基於SqlSugar的開發框架循序漸進介紹(5)-- 在服務層使用介面注入方式實現IOC控制反轉

基於SqlSugar的開發框架循序漸進介紹(6)-- 在基礎類別介面中注入使用者身份資訊介面 

基於SqlSugar的開發框架循序漸進介紹(7)-- 在檔案上傳模組中採用選項模式【Options】處理常規上傳和FTP檔案上傳

 《基於SqlSugar的開發框架循序漸進介紹(8)-- 在基礎類別函數封裝實現使用者操作紀錄檔記錄

基於SqlSugar的開發框架循序漸進介紹(9)-- 結合Winform控制元件實現欄位的許可權控制

基於SqlSugar的開發框架循序漸進介紹(10)-- 利用axios元件的封裝,實現對後端API資料的存取和基礎類別的統一封裝處理

基於SqlSugar的開發框架循序漸進介紹(11)-- 使用TypeScript和Vue3的Setup語法糖編寫頁面和元件的總結

基於SqlSugar的開發框架循序漸進介紹(12)-- 拆分頁面模組內容為元件,實現分而治之的處理

基於SqlSugar的開發框架循序漸進介紹(13)-- 基於ElementPlus的上傳元件進行封裝,便於專案使用

基於SqlSugar的開發框架循序漸進介紹(14)-- 基於Vue3+TypeScript的全域性物件的注入和使用

基於SqlSugar的開發框架循序漸進介紹(15)-- 整合程式碼生成工具進行前端介面的生成

基於SqlSugar的開發框架循序漸進介紹(16)-- 工作流模組的功能介紹

 《基於SqlSugar的開發框架循序漸進介紹(17)-- 基於CSRedis實現快取的處理

基於SqlSugar的開發框架循序漸進介紹(18)-- 基於程式碼生成工具Database2Sharp,快速生成Vue3+TypeScript的前端介面和Winform端介面