Spring Security實現短信驗證碼登錄


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的校驗就好了。這樣一來,實現的邏輯如下:

在user表中添加一個字段verification_code,等用戶獲取手機驗證碼時,后端將返回給用戶的驗證碼進行加密,加密方式和對password的處理一樣,然后保存到 verification_code 字段中。然后用戶在輸入手機號和驗證碼登錄時,我們根據手機號獲取用戶的username,然后將username和驗證碼傳給獲取token的接口,讓這個接口以為我們使用的是用戶名密碼的登錄方式,但是這個password值需要使用 verification_code字段的值來代替就好了。

那又怎么將 verification_code的值替換password值返回給Spring Security呢?

我們有一個UserServiceDetail類,實現了UserDetailsService接口,其中重載了方法:loadUserByUsername,Spring Security就是從這里拿到user表的password后進行比較判斷的。那我們修改這個方法,如果是驗證碼登錄方式,就把password屬性設置成 verification_code的值,這樣就欺騙了Spring Security,讓它拿加密后的驗證碼去和password屬性比較,如果相等也表示登錄成功了。具體代碼如下:

這種做法確實有點繞,也不是正規的做法,但是因為我們對Spring Security這個流程有了一定程度的理解,就可以這么取巧來先達到目的,之后可能需要按正規的方式來做,因此不建議效仿,只是提供了另一種一種思路而已。

 

原文地址:https://www.nndev.cn/archives/1882


免責聲明!

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



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