Java項目筆記之短信驗證碼、用戶登陸


不點藍字,咱們哪來故事?



騾窩窩02——短信驗證碼、用戶登陸

短信驗證碼:

需求分析:

  1. 獲取手機號碼;前端

  2. 生成驗證碼;java

  3. 發送短信;web

  4. 短信驗證碼存儲面試

    設計 verify_code : pahone;value就是驗證碼,同時設置key的有效時機5分鐘;spring

  5. 獲取手機號碼與驗證碼code;數據庫

    將手機號拼接成key:verify_code : pahone,經過key去取值;編程

  6. 對比驗證碼code與以前存的驗證碼;小程序

    將取到的值和用戶輸入的驗證碼作對比。後端

問題點
api

  • 第一次請求存數據;

  • 第二次請求要取數據;


須要作到請求之間的數據共享

  • cookie:客戶端技術,數據存在瀏覽器;主要弊端:安全性不高

  • session:服務端技術,數據存在服務端是可行的,可是:

    • 操做複雜須要存儲數據較多(倒計時等操做不方便);

    • 若是是先後端分離項目,建議不要用session;由於session在擴展小程序、移動端等開發時存在感不強(不符合通用編程);

  • Redis:Redis的特色:緩存數據庫,易控制失效時間;

    延伸:MySQL、MongoDB也能夠實現驗證碼的存儲,可是沒法自動進行有效時間的控制,須要額外的代碼加以控制;

    • Redis能夠知足多個請求間的數據共享;

    • Redis自己就是臨時數據存儲數據庫,天生支持數據時效性,驗證碼恰好須要這個特色;


Redis中k-v對該怎麼設計:

將他們簡化成一個Map,在思考map中應該存什麼樣的k-v對;

  1. key怎麼設計?(惟一性、可讀性、時效性、靈活

    • 單獨用手機號作key是可行的,可是可讀性很差——加上前綴可讀性更好

    • 時效性可直接設置key的失效時間;

  2. value怎麼設計(靈活)?

    • 根據value的特色設計便可;


頁面的倒計時:

前端代碼:

表現層:

業務層:


將驗證碼存到Redis中:

先添加依賴,添加到哪?共用放core;

Redis的配置:不放在core中,由於有可能被覆蓋,直接對子項目作配置便可;

core建立Redis文件夾統一管理Redis相關;

業務層:

建立方法:

實現:

完成k-v的存儲和時間設置:

測試:

405:請求方式不匹配;

去Redis中查看數據是否存儲完成;


驗證過程;


測試:

從新發送短信驗證碼以後原來的值被覆蓋了;因此要控制發送驗證碼的頻率

拓展:控制發送驗證碼的頻率

思路:在Redis中存發送次數的限制,還有時效性,key爲3,發一次減1,在發送短信以前判斷一下key是否知足發送條件;


真實短信發送:

短信發送原理

本身的短信發送:

企業的發短信:

短信網關:京東萬象:https://wx.jdcloud.com/api-66


怎麼用別人的接口來發短信:

須要藉助短信網關的API:發起HTTP請求

//https://way.jd.com/chuangxin/dxjk?mobile=18487143792&content=【創信】你的驗證碼是:5873,3分鐘內有效!&appkey=87f7d7e66d93f1022d52dfecf6e704ae

怎麼發起http請求:RestTemplate類。springmvc提供用於專門發起http請求的操做類;

多項目結構千萬別按提示導入項目導入依賴:

導入依賴:

代碼:

數據寫死的配置,改源代碼很差,路徑放到配置文件中application.properties;

如何用到路徑等配置

表現層:

業務層:

技術延伸

短信發送實際上也是項目之間的交互。要知道之後查詢天氣、身份覈驗等等公共的接口實現,也是項目之間的操做,要舉一反三。(若是別人提供的項目的API,咱們就能夠經過交互的方式來利用他的功能來實現本身的目的);


http和https他們的區別

區別是https加密了;

數據加密傳輸,是HTTP和HTTPS之間的本質性區別。


鍛鍊本身面試時項目經驗的表達能力:

口述:需求分析的過程,功能是怎麼實現的,要注意哪一些細節,口述代碼思路和流程思路;



細節優化

_class屬性排除

Redis存儲的時候,多出來的_class屬性;

配置類中拷貝一個添加一個配置:

將數據庫中的class數據刪除掉,再添加就不會有class屬性了;


統一異常處理

爲何要統一異常處理(AOP [動態代理] )

自定義異常的處理中代碼出現重複了。如何減小重複:

  • 模板方法:抽取的業務方法沒辦法統一塊兒來;因此能夠但不合適;

  • 最佳實踐:面向切面編程(AOP),在不改變業務代碼的前提下,經過動態代理的方式對代碼功能的加強;


代碼實現

在api子項目中建立包,專門管理advice加強類;

各類不一樣的異常,怎麼區分開來作處理:@ExceptionHandler明確標記方法可處理哪一種類型的異常;

加強處理器中的方法與請求映射的方法設計同樣,共享數據用model,參數接收用形參;

此時可能會出現異常的代碼變成了這樣:

Redis key重設計

枚舉類:

java枚舉類的用法一:常量,使用java枚舉類能夠替代常量,由於常量沒有命名空間,使用起來不是很是清晰,若是使用java枚舉類,就能夠清晰地讀懂代碼,代碼可維護性強

這樣的代碼中的常量怎麼優化?

  • 常量類統一管理的方式:

  • 使用枚舉類來管理常量:(枚舉中常量不容許重複和key不重複天生一對)


  • key 須要靈活:如何改造?



面試點:

在代碼中的應用:用枚舉類來管理Redis的key



用戶登陸:

需求分析

  1. 獲取參數用戶名和密碼;

  2. 經過數據庫查詢用戶對象;

  3. 根據用戶對象是否存在判斷是否已經登陸;

  4. 須要將用戶信息進行緩存,目的是下一次訪問時,經過這個信息進行登陸判斷;

  5. 登陸判斷:

    • 獲取登陸的令牌和參數

    • 經過令牌獲取以前緩存起來的用戶信息


用戶信息數據存在哪裏

  1. Session:之前的方式,將用戶的信息存在session中。原理Session的存儲依賴於cookieCookie負責存Session中的jSessionIdsession中的用戶數據存在服務端;Cookie裏的jSessionId在瀏覽器,用戶再次請求的時候,經過request對象獲取到Cookie而後拿到jSessionId,再經過jSessionIdSession中查詢用戶的信息,根據查詢結果判斷是否登錄過;

    弊端:禁用cookie後將沒法驗證須要經過另外的方式處理,麻煩,數據量大服務器的性能降低;


  2. Redis數據庫存儲:(最佳實踐)快,而且方便控制超時時間;



    • 經過UUID建立出一個隨機的 登陸令牌,String token = 隨機碼;將token的隨機碼做爲Redis的key,user對象做爲value,存在Redis中;

    • 返回token隨機碼到客戶端;注意客戶端須要將token保存起來

    • 客戶端下一次訪問時,經過http請求頭的方式將token傳到後臺

    • 後臺驗證時,經過request對象獲取到請求頭,拿到token隨機碼;再用token隨機碼做爲key查詢Redis中的用戶是否存在,判斷用戶是否已經登陸過;


用戶登陸流程分析:

代碼實現:

明白請求的訪問地址和類型和參數:

表現層:

業務層:

持久層:

業務層完善:

表現層:

將數據存到Redis中:

key的可讀性:

將token傳到客戶端保存起來:


參數怎麼設計,才能去前臺回調函數的參數格式對應起來?

測試:查看參數是否傳到了前臺



java學途

只分享有用的Java技術資料 

掃描二維碼關注公衆號

 


筆記|學習資料|面試筆試題|經驗分享 

若有任何需求或問題歡迎騷擾。微信號:JL2020aini

或掃描下方二維碼添加小編微信

 




小夥砸,歡迎再看分享給其餘小夥伴!共同進步!




本文分享自微信公衆號 - java學途(javaxty)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索