微信掃碼登錄技術實現的簡單思考


微信掃碼登錄是經常用到的的騷操作,但是,其實現的思路是怎樣的,可能很多人都沒有去思考過。記得曾經在一次面試當中,面試官就曾問過微信掃碼登錄的實現思路,這次,以微信讀書網頁版掃碼登錄為例子,聊聊我對微信掃碼登錄技術實現思路一些思考。

以谷歌瀏覽器來做本次分析,打開F12,准備隨時觀察http連接狀況。

接下來用谷歌瀏覽器打開網頁版微信讀書,點擊登錄,會彈出一個二維碼:

image

可以看到,在二維碼彈出來的時候,前端調用了后端兩個接口,一個是getuid(),一個是getinfo(),這里面涉及到哪些邏輯實現呢?

image

稍微思考一下,其實很好理解,每個隨機生成的二維碼,其實都是一個uuid碼,也就是說,在點擊登錄的時候,會執行一個getuid()方法,去調用后端API:web/login/getuid,然后返回一個隨機生成的uuid碼。當這個uuid碼返回到前端上時,就會以二維碼的形式展示。根據uuid如何生成二維碼,我后面再寫一篇小白文來分析下。

在谷歌瀏覽器F12調出的控制台頁面,點擊getuid(),在右邊欄的Preview框里,可看到該方法返回一個隨機生成的uuid:38e673a9-5bd3-4f0c-ba2f-62ab376372a9

image

返回uuid的同時,還調用了另一個getinfo()方法——可見,這應該是getuid調用成功后的回調方法,也就是當getuid()執行成功后,在得到一個uid時,就立馬調用getinfo()方法,同時將生成的uid當做參數傳給getinfo(),讓其去訪問后端API。

image

當沒有用手機微信進行掃碼操作時,會看到getinfo()一直沒有返回值,這時,它傳給后端的uuid正在做輪詢查詢操作,在某段時間內,若沒有輪詢成功,就會斷開連接,接口調用失敗。

image

到這里,可以簡單歸納下網頁版微信登錄頁面生成二維碼的流程,即,在點擊登錄按鈕時,代碼層面會執行getuid()方法去調用后端API接口,即“https://weread.qq.com/web/login/getuid”,后台將隨機生成一個唯一uid返回。前端得到正常返回狀態后,就會將參數傳給getuid的回調方法getinfo({"uid":"38e673a9-5bd3-4f0c-ba2f-62ab376372a9"}),該getinfo方法會將uid參數傳給后端API接口“https://weread.qq.com/web/login/getinfo”,這時,后端內部將一直做輪詢拿uid去redis查詢,若能查詢成功,即登錄成功,反之,則連接超時失敗。

下面用兩段偽代碼來說明下大概代碼邏輯:

一.前端React獲取uuid並回調給getinfo()偽代碼:

 1 export const getuid=(params={},queue='getuid')=>dispatch=>{
 2     http.post({
 3         url:'https://weread.qq.com/web/login/getuid',
 4         params:params,
 5         queue:queue,
 6         callback:(res)=>{
 7             //getuid方法執行成功,返回{uid: "38e673a9-5bd3-4f0c-ba2f-62ab376372a9"},
//回調執行getinfo()
8 dispatch(getinfo({uid:res.uid})) 9 } 10 }); 11 } 12 13 export const getinfo=(params={},queue='getinfo')=>dispatch=>{ 14 http.get({ 15 url:'https://weread.qq.com/web/login/getinfo', 16 params:params, 17 queue:queue, 18 callback:(res)=>{ 19 //若登錄成功,應該重定向到已登錄狀態的主頁 20 } 21 }); 22 }

 

二.后端API接口/web/login/getinfo偽代碼:

 1 public String getinfo(String uid){
 2     ......
 3         //循環查詢uid在redis里是否存在值
 4         while(true){
 5             String user=redisTemplate.opsForValue().get(uid);
 6             if(user!=null){
 7                 return user;
 8             }
 9         }
 10     ......
 11 }

 

用一個時序圖來簡單表示這個過程:

image

那么,什么時候才能通過uid去redis查詢才能得到返回值呢?

這時候,就要說到掃碼階段了

當getinfo(String uid)接口在輪詢查詢redis是否有key為uid的值時,用戶拿出手機,在二維碼有效時間內,用微信掃一掃進行掃碼操作,這時,手機上就會出現該頁面展示:

image-20210309231421142

若點擊登錄,網頁版微信讀書就會刷新,進入到已登錄狀態的首頁。

這個過程很好理解,即在掃碼后,手機端會從二維碼中獲取到uid,這時,若點登錄,就會將uid與微信用戶信息一塊包裝成json格式post提交給后端,然后在后端接口中,將以uid:user的key-value形式set插入到redis數據庫。這時,另一邊正在以uid當做key值輪詢去redis是否有值的getinfo(String uid)方法,通過類似redisTemplate.opsForValue().get(uid)的方式,正好就能通過uid把剛插入redis的user信息查詢出來,最后返回給PC端的微信讀書前端,即登錄成功。

最后,完整的流程可以時序圖這樣表示:

 

image

PC端微信讀書登錄成功的時候,頁面重新做了刷新,應該是在后台做了接口重定向,具體如何重定向,感興趣的朋友可以自行思考研究,微信掃碼登錄大體上就是這個思路,但細節方面應該會有更多相關校驗在里面。

這里主要是分析下它的整體實現思路。

值得提一點是,PC端微信讀書前端其實做了反調試,但沒關系,它這個反調試的做法很容易破解,可參考我的做法,即打開谷歌瀏覽器,按F12,調出控制台,把這個圖標點亮,就可以關閉微信讀書前端自帶的反調試設置了。

image


免責聲明!

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



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