在一個應用系統的開發框架中,往往很多地方需要用到緩存的處理,有些地方是為了便於記錄用戶的數據,有些地方是為了提高系統的響應速度,如有時候我們在發送一個簡訊驗證碼的時候,可以在緩存中設置幾分鐘的過期時間,這樣驗證簡訊驗證碼的時候,就會自動判斷是否過期了。本篇隨筆結合CSRedis的使用,介紹如何實現緩... ...
在一個應用系統的開發框架中,往往很多地方需要用到緩存的處理,有些地方是為了便於記錄用戶的數據,有些地方是為了提高系統的響應速度,如有時候我們在發送一個簡訊驗證碼的時候,可以在緩存中設置幾分鐘的過期時間,這樣驗證簡訊驗證碼的時候,就會自動判斷是否過期了。本篇隨筆結合CSRedis的使用,介紹如何實現緩存的初始化及使用的處理。
1、在基於.netCore的Web API後端使用CSRedis
關於CSRedis的使用,我們可以參考Github網站:https://github.com/2881099/csredis 進行瞭解。
首先我們在使用前,需要添加對應的程式集應用。
Package Name | NuGet | Downloads | |
---|---|---|---|
CSRedisCore | |||
Caching.CSRedis | IDistributedCache |
CSRedisCore是必須的,而Caching.CSRedis則是在用到分散式緩存的時候需要用到。
初始化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端界面》
專註於代碼生成工具、.Net/.NetCore 框架架構及軟體開發,以及各種Vue.js的前端技術應用。著有Winform開發框架/混合式開發框架、微信開發框架、Bootstrap開發框架、ABP開發框架、SqlSugar開發框架等框架產品。
轉載請註明出處:撰寫人:伍華聰 http://www.iqidi.com