Spring Security默認的一個實現是使用用戶名密碼登陸,當初咱們在開始作項目時,也是先使用這種登陸方式,並無多考慮其餘的登陸方式。然後面需求愈來愈多,咱們須要支持短信驗證碼登陸了,這時候再看了解Spring Security中如何實現短信驗證碼登陸。數據庫
這裏有一篇文章:SpringBoot 集成 Spring Security(8)——短信驗證碼登陸,提供了一種比較正規的方法來解決這個問題,好比須要寫filter類等等。可是咱們須要臨時性解決這個問題,因而就經過了其它很是規手段來實現。後端
咱們知道默認的方式是,數據庫裏的user表保存了username和password,其中後者是密文保存。當用戶登陸時,Spring Security會拿用戶傳過來的密碼進行加密後和數據庫中password的值進行比較,相同則登陸成功。若是是短信登陸,須要傳入的是手機號和驗證碼,好比叫phone和verification_code。加密
在咱們的數據庫中,username和phone都是惟一的,那咱們想達到的效果就是,讓對phone和 verification_code的校驗轉變成對username和password的校驗就行了。這樣一來,實現的邏輯以下:.net
在user表中添加一個字段verification_code,等用戶獲取手機驗證碼時,後端將返回給用戶的驗證碼進行加密,加密方式和對password的處理同樣,而後保存到 verification_code 字段中。而後用戶在輸入手機號和驗證碼登陸時,咱們根據手機號獲取用戶的username,而後將username和驗證碼傳給獲取token的接口,讓這個接口覺得咱們使用的是用戶名密碼的登陸方式,可是這個password值須要使用 verification_code字段的值來代替就行了。code
那又怎麼將 verification_code的值替換password值返回給Spring Security呢?blog
咱們有一個UserServiceDetail類,實現了UserDetailsService接口,其中重載了方法:loadUserByUsername,Spring Security就是從這裏拿到user表的password後進行比較判斷的。那咱們修改這個方法,若是是驗證碼登陸方式,就把password屬性設置成 verification_code的值,這樣就欺騙了Spring Security,讓它拿加密後的驗證碼去和password屬性比較,若是相等也表示登陸成功了。具體代碼以下:token
這種作法確實有點繞,也不是正規的作法,可是由於咱們對Spring Security這個流程有了必定程度的理解,就能夠這麼取巧來先達到目的,以後可能須要按正規的方式來作,所以不建議效仿,只是提供了另外一種一種思路而已。接口