Web端掃碼登錄的原理和實現講解
1 概述
在日常 Web 端產品的使用中,一般都會支持掃碼登錄,這種方式操作簡單,相對傳統的手機號登錄等方式速度更快、安全性更高,還可以增加自傢產品的粘合度。
2 登錄原理
掃碼登錄本質是解決將 APP 端的用戶登錄信息(通常是 Token)通過掃碼的形式安全穩定地同步給 Web 端。
1)用戶打開 Web 端網頁,進入掃碼登錄的界面;
2)從 Web 端服務器獲取二維碼的圖並獲取其狀態;
3)Web 端服務器在生成二維碼時,會生成一個 uuid 和二維碼進行關聯,並將 uuid 存入 db 記錄中;
4)用戶打開 APP 端,對著二維碼進行掃碼授權操作;
5)APP 客戶端從二維碼中讀取到 uuid,帶著 APP 內的身份信息訪問 APP 端服務器;
6)APP 端服務器獲取到用戶的身份信息後,將用戶 id 更新到 db 中對應 uuid 的記錄中,此時 Web 服務器就能拿到對應的用戶 id,之後生成登錄身份信息返回給瀏覽器,即用戶在 Web 端完成瞭登錄;
3 實現方案
基於以上分析,我們可以將掃碼登錄分為兩個步驟:獲取掃碼狀態和獲取用戶登錄信息。
3.1 獲取掃碼狀態
用戶在 Web 端頁面看到二維碼信息後,會使用客戶端進行掃碼授權,而 Web 端需要盡快獲取到二維碼的狀態(已掃碼、已過期、已取消、已授權)並同步到網頁中展示給用戶, 現在有3種方案:
3.1.1 長鏈接
Web 端訪問服務器獲取二維碼狀態時,服務器是阻塞瞭請求,等到二維碼的狀態變更後才會返回結果,這種請求都會有超時配置(通常是幾分鐘),但又不能無限等待。
方案優點:
- 減少不必要的資源訪問浪費;
- 可以準確區分惡意訪問(掃描漏洞,後面的部分會對這部分進行闡述)並進行限流;
- 當二維碼狀態變更時,相對於下面的定時輪詢方案有更快的響應速度;
方案缺點:
- 占用服務端大量連接數;
- 由於超時時間通常比較長,需要web端和nginx對這些請求進行特殊的超時配置;
3.1.2 輪詢
Web 端每隔一個固定時間(為瞭更好的用戶體驗通常選擇為 1 秒)訪問服務器獲取二維碼的狀態並進行展示。
方案優點:
- 符合常規思維,開發模式比較簡單易維護;
- 相比阻塞等待方案能夠快速釋放服務端的連接;
- 對於服務端的變更升級也更加友好,因為變更升級會導致服務重啟,采用阻塞方案則可能會造成部分連接斷開;
方案缺點:
- 如果掃碼登錄請求訪問量大,會導致服務端的訪問量一直處於高位;
- 產生瞭大量的無用訪問,造成資源浪費;
- 無法準確區分惡意訪問並對其進行合理限流;
3.1.3 長輪詢
長輪詢即結合瞭長鏈接和定時輪詢的優點,Web 端訪問服務器獲取二維碼狀態時,服務器依然會阻塞瞭請求,但是超時時間會相對比較短(比如15秒),超時後 Web 端會繼續發起請求,如此往復。
方案優點:
- 結合瞭阻塞等待和定時輪詢的優點,削弱瞭兩個方案的的缺點;
方案缺點:
- 讓 Web 端開發邏輯更加復雜,相當於同時實現瞭兩種方案;
3.1.4 方案選擇
三種方案各有優缺點,應該結合業務進行選擇。
先以微信公眾平臺為例,進入其掃碼登錄頁,就會發現密密麻麻的調用獲取掃碼狀態請求過程,很明顯是采用瞭輪詢方案。
再看看其他廠傢選擇:
平臺方案微信開放平臺長輪詢微信公眾平臺輪詢京東輪詢淘寶&&天貓輪詢百度長輪詢B 站輪詢快手長鏈接
從上面可以看出目前主流方案是定時輪詢,這是由於掃碼登錄本身也是低頻操作,並不會造成很大量的請求,但優點又比較突出。
3.2 獲取登錄信息
當用戶掃碼登錄後,Web 服務器如何將用戶信息(如 Token)同步給 Web 端。
3.2.1 返回 Token
指直接返回用戶登錄信息 Token。
方案優點:
- 流程簡單,完成掃描授權後流程後直接結束;
方案缺點:
- 無法支持多站點跨站登錄,即 Web 端服務器隻能給一個業務提供掃碼登錄功能;
- 由於直接返回瞭 Token,安全風險等級較高;
3.2.2 授權 Ticket
Web 端服務器在掃碼完成後,返回的是一個授權 Ticket(也可以直接返回帶 Ticket 的授權 url, 便於 Web 端直接跳轉),之後需要 Web 端帶著這個 Ticket 調用目標服務器的接口進行身份的驗證同步,如圖所示:
方案優點:
- 沒有直接傳遞 Token,安全性更好;
- 可以支持多站點跨站登錄身份信息的同步,適用於服務於多站點的掃碼登錄服務;
方案缺點:
- 實現邏輯較為復雜,需要維護完整的授權 Ticket 生成、校驗以及失效邏輯;
3.2.3 方案選擇
平臺方案微信開放平臺授權Ticket微信公眾平臺Token京東授權Ticket淘寶&&天貓授權Ticket百度授權TicketB 站授權Ticket快手授權Ticket
經過調研發現,在國內互聯網各大廠商中返回授權 Ticket 的方案被較多采用,這也由於各傢旗下擁有眾多 PC Web 站,直接返回 Token 的方案無法多站點的登錄信息同步,而上面表格中亦有一個另類——微信公眾平臺,大概與其產品獨立性有關。
4 安全防護
前面提到,掃碼登錄的本質是通過掃碼手段安全穩定地同步用戶信息。那麼我們可以通過哪些手段提高同步過程中的安全性?
4.1 定時過期
每個二維碼都有一個唯一的 uuid 與之對應,為瞭防止惡意人員通過接口遍歷查詢以獲取之前已經被掃的二維碼信息,數據不能永久存儲於db中,需要完成掃碼後從 db 刪除或者定期過期清除。
4.2 UUID不可遍歷
簡單的方案是將自增 ID 和一個固定 salt 進行 md5 之後生成一個字符串作為uuid;也可以通過 UUID.randomUUID()
生成一個隨機字符串。當然,還可以采用對稱加密的方式存儲一些加密信息。
4.3 簽名驗證
這個方式關鍵點在於將 uuid 和請求中的 Cookie 或參數信息經過哈希算法得到一個 signature 值,此時即使有人破解瞭 uuid 的生成規則,隻能生成uuid,但是無法獲知對應 uuid 生成時對應的 Web 端狀態(Cookie),因此破解瞭 uuid 後也無法獲取對應 signature 值,也就無法獲取二維碼狀態。
4.4 合理限流
一般是在獲取二維碼階段對來源 IP 進行訪問的限制。
當然掃描二維碼階段也可以做限流,但是如果采用是定時輪詢方案,由於訪問次數太多,無法做到精確識別和控制,可操作性不強;而如果采用的是阻塞等待方案,也能進行限流,但是如果已經采用瞭上面參數簽名驗證,則可以把惡意用戶都收口在獲取二維碼階段,在這個階段限流的意義不大。
5 總結
其實每個方案都有其適用的場景和階段,沒有嚴格意義上的孰優孰劣,這個從各互聯網公司的選擇中也能看出,而要基於自身的需要選擇最合適的方案,切忌盲目選擇最復雜的方案。
到此這篇關於Web端掃碼登錄的原理和實現講解的文章就介紹到這瞭,更多相關掃碼登錄的原理和實現內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- 淺談node使用jwt生成的token應該存在哪裡
- 關於JWT與cookie和token的區別說明
- JWT登錄認證實戰模擬過程全紀錄
- java開發web前端cookie session及token會話機制詳解
- Java面試題沖刺第二十六天–實戰編程