首頁/ 汽車/ 正文

微信掃碼登入之最簡實現

最近開發某應用的PC端後臺管理時,突然對登入頁面的賬號密碼還有圖片識字驗證碼感到厭煩了,不僅填寫麻煩,要記賬號密碼也麻煩。為什麼不嘗試用微信掃碼登入呢?功能實現後,我整理出來分享給大家(友情提示:閱讀本文需要比較熟悉微信公眾號的相關開發,前端框架是基於vue3的element plus,後端是。net6。0 的c# )。本文是針對PC上web應用的登入場景下,實際上我以前做過桌面端wpf程式的微信掃碼登入,大致流程和程式碼也是一樣的,也就是說所有客戶端顯示二維碼,讓使用者掃碼登入,處理流程大體是一樣,差異只是因為客戶端不同,掃碼成功後服務端傳送登入資訊給客戶端所採用的推送方式也不同。

一 功能設計描述

在PC上開啟後臺登陸頁,無賬號密碼錄入框,只顯示一個二維碼。拿出手機微信掃碼,手機端顯示登入成功的提示,然後pc端的登入頁面自動跳轉到登入後的下個頁面。

二開發前提條件:

作為管理後臺,要用微信掃碼登入,就表示登入使用者在資料庫裡必須已記錄了在自家公眾號下的openid。簡單說,得有公眾號,使用者表裡得有使用者的openid(如何獲取可以參考微信公眾號開發文件),因為如何建立後臺管理使用者大家都各有各的做法,我這裡就很簡單,發個連結給使用者微信,讓他點開獲取微信身份授權後,再填入他在管理後臺的賬號密碼,連同微信授權code一起發到服務端即可。介面地址必須在公眾號的授權回撥域中配置好。更詳細內容請參考微信公眾號開發的網頁授權部分。

三 程式流程設計

登陸頁面初始化,生成隨機字串sessionid, 二維碼連結帶上sessionid ,當用微信掃二維碼時,服務端獲得使用者微信openid進而透過openid找到使用者,核查合法後把使用者資訊和sessionid一起寫入快取。anxios則用sessionid作為引數查詢服務端的登入結果,服務端則從快取讀取該sessionid的登入資訊返回給客戶端,客戶端獲得登入資訊後存在本地並跳轉主頁,這是大致的流程。

由於掃碼成功後,登入頁面需要自動完成登入過程,這裡就涉及了一個web開發常見的問題-推送,即掃碼後服務端需要主動把登入結果傳送給登入頁面。本著用最簡單方式實現的目的,我這裡就是直接就用axios發一個正常請求,然後把 connect timeout引數設定大一點,我打算透過服務端hold住執行緒輪詢資料來實現。當然更完美一點的方案,就是用settimeout之類讓請求輪詢執行,或者長輪詢,或者使用websocket等方法,因篇幅限制,不展開細講。

1 客戶端 登入頁面vue程式碼,我過濾了ui樣式以及細節處理的程式碼,就是一個顯示二維碼的vue元件vue-qr,頁面初始化生成一個sessionid,拼在一個服務端介面地址上,形成二維碼元件的連結。頁面初始化同時也用sessionid發起查詢登入結果請求。

2 服務端查詢登入結果介面程式碼,因為邏輯相對簡單,所以我先講這個。簡單描述就是收到客戶端請求後,用sessionid查詢快取,用每隔2秒輪詢查詢,一直到查到有結果才返回客戶端。客戶端收到登入結果就進行下一步處理。

///

/// 返回登入結果 /// /// 客戶端sessionid /// [EnableCors] [HttpGet] [AllowAnonymous] public object CheckLogin(string sessionId) { var loginResult = Redis_Utility。Get($“login_{sessionId}”); while (loginResult == null) { Thread。Sleep(2000); loginResult = Redis_Utility。Get($“login_{sessionId}”); } return loginResult; }

3 二維碼對應服務端程式碼。這個介面地址也就是二維碼的連結,即使用者微信掃碼後開啟的地址,此時code引數為空,服務端會把當前頁面重定向到微信的授權頁面,獲取到微信授權code後再跳轉回當前介面地址,此時code不為空了,服務端拿到code,結合公眾號的appid accesstoken之類就可以從微信得到使用者的openid,拿到openid就可以查詢使用者表,剩下的不用多介紹了吧。實際開發時 為了使得程式更簡單易維護,也可以把介面拆分開,一個是掃碼介面,一個是微信授權後跳轉回來的介面,我為了省事,兩個介面合併在一起,透過檢查code是否為空,識別出是掃碼還是微信授權後跳轉回來。登入成功後 輸出一段html程式碼在手機上顯示。

///

/// 登入介面 /// /// 客戶端sessionid /// 公眾號授權code /// {userInfo:xxxx, token:xxxx} [HttpGet] [AllowAnonymous] public async Task Login(string sessionId, string? code = null) { if (string。IsNullOrEmpty(code)) { string redirect_uri = HttpUtility。UrlEncode(Request。GetDisplayUrl());//授權後跳轉回來 Response。Redirect($“https://open。weixin。qq。com/connect/oauth2/authorize?appid={APPID}&redirect_uri={redirect_uri}&response_type=code&scope=SCOPE&state=STATE#wechat_redirect”); } else { string openId = await WechatServices。GetOpenId(code); var result = adminServices。Login(openId); if (result。Code == 0) { Redis_Utility。Set($“expert_admin_login_{sessionId}”, result。Data, 1); string html = htmlTemp。Replace(“$content”, “登入成功”); await Response。WriteAsync(html); } else { await Response。WriteAsync(result。Message); } } }

碼字辛苦,如果覺得有參考價值請點個贊,如果有看不懂的地方歡迎提問,如果有更好更簡單的辦法歡迎指教!

相關文章

Copyright © 2022百聞網
頂部