由於掃碼登錄比賬號密碼登錄更方便、快捷、靈活,在實際使用中更受到用戶的歡迎。
本文主要介紹了掃碼登錄的原理及整體流程,包含了二維碼的生成/獲取、過期失效的處理、登錄狀態的監聽。
掃碼登錄的原理
整體流程
為方便理解,我簡單畫了一個 UML 時序圖,用以描述掃碼登錄的大致流程!
總結下核心流程:
-
請求業務服務器獲取用以登錄的二維碼和 UUID。
-
通過 websocket 連接 socket 服務器,並定時(時間間隔依據服務器配置時間調整)發送心跳保持連接。
-
用戶通過 APP 掃描二維碼,發送請求到業務服務器處理登錄。根據 UUID 設置登錄結果。
-
socket 服務器通過監聽獲取登錄結果,建立 session 數據,根據 UUID 推送登錄數據到用戶瀏覽器。
-
用戶登錄成功,服務器主動將該 socker 連接從連接池中剔除,該二維碼失效。
關於客戶端標識
也就是 UUID,這是貫穿整個流程的紐帶,一個閉環登錄過程,每一步業務處理都是圍繞該次的 UUD 進行處理的。UUID 的生成有根據 session_id 的也有根據客戶端 ip 地址的。個人還是建議每個二維碼都有單獨的 UUID,適用場景更廣一些!
關於前端和服務器通訊
前端肯定是要和服務器保持一直通訊的,用以獲取登錄結果和二維碼狀態。看了下網上的一些實現方案,基本各個方案都有用的:輪詢、長輪詢、長鏈接、websocket。也不能肯定的說哪個方案好哪個方案不好,只能說哪個方案更適用於當前應用場景。個人比較建議使用長輪詢、websocket 這種比較節省服務器性能的方案。
關於安全性
掃碼登錄的好處顯而易見,一是人性化,再就是防止密碼泄漏。但是新方式的接入,往往也伴隨着新的風險。所以,很有必要再整體過程中加入適當的安全機制。例如:
- 強制 HTTPS 協議
- 短期令牌
- 數據簽名
- 數據加密
掃碼登錄的過程演示
代碼實現和源碼后面會給出。
開啟 Socket 服務器
訪問登錄頁面
可以看到用戶請求的二維碼資源,並獲取到了 qid
。
獲取二維碼時候會建立相應緩存,並設置過期時間:
之后會連接 socket 服務器,定時發送心跳。
此時 socket 服務器會有相應連接日志輸出:
用戶使用 APP 掃碼並授權
服務器驗證並處理登錄,創建 session,建立對應的緩存:
Socket 服務器讀取到緩存,開始推送信息,並關閉剔除連接:
前端獲取信息,處理登錄:
掃碼登錄的實現
注意:本 Demo 只是個人學習測試,所以並未做太多安全機制!
Socket 代理服務器
使用 Nginx 作為代理 socke 服務器。可使用域名,方便做負載均衡。本次測試域名:loc.websocket.net
websocker.conf
Socket 服務器
使用 PHP 構建的 socket 服務器。實際項目中大家可以考慮使用第三方應用,穩定性更好一些!
QRServer.php