PC 端微信掃碼注冊(cè)和登錄實(shí)例
PC 端微信掃碼注冊(cè)和登錄
一、前言
先聲明一下,本文所注重點(diǎn)為實(shí)現(xiàn)思路,代碼及數(shù)據(jù)庫設(shè)計(jì)主要為了展現(xiàn)思路,如果對(duì)代碼效率有著苛刻要求的項(xiàng)目切勿照搬。
相信做過微信開發(fā)的人授權(quán)這塊都沒少做過,但是一般來說我們更多的是為移動(dòng)端的網(wǎng)站做授權(quán),確切來說是在微信端下做的一個(gè)授權(quán)。今天遇到的一個(gè)問題是,項(xiàng)目支持微信端以及 PC 端,并且開放注冊(cè)。要求做到無論在 PC 端注冊(cè)或者是在微信端注冊(cè)之后都可以在另外一個(gè)端進(jìn)行登錄。也就是說無論 PC 或是微信必須做到"你就是你"(通過某種方式關(guān)聯(lián))。
二、尋找解決方案
按傳統(tǒng)的方式來思考,微信端完全可以通過授權(quán)進(jìn)行注冊(cè),但是PC端呢,傳統(tǒng)的方式無非就是填填手機(jī)號(hào)碼啊,或者 Email 等等。如果采用這種方式注冊(cè),會(huì)產(chǎn)生下面這的問題
1.我先在微信端授權(quán)注冊(cè),那么如果我要登錄PC端還是得進(jìn)行注冊(cè)。
對(duì)此解決方案可以為:微信授權(quán)注冊(cè)后“強(qiáng)制”要求用戶必須填寫基本信息,如手機(jī)號(hào)、Email 。這樣我們可以通過某種方式為用戶生成PC端登錄的賬號(hào)密碼.例如以用戶的 nickname 為賬號(hào),手機(jī)號(hào)碼為密碼,等等方式。
弊端:用戶體驗(yàn)不好,再者有安全隱患。畢竟你的微信昵稱, Email 或者手機(jī)號(hào)碼都是暴露的。
2.如果我先在 PC 端注冊(cè),我在微信授權(quán)的時(shí)候怎樣關(guān)聯(lián)移動(dòng)端, 當(dāng)然,凡是問題總會(huì)有解決方案的。思路如下:
方案一:當(dāng)用戶在 PC 端注冊(cè)后,“強(qiáng)制” 用戶必須填寫微信昵稱。以此作為微信授權(quán)時(shí)的關(guān)聯(lián)條件。但是很遺憾,微信昵稱可以改,不是唯一的怎么可以用來做關(guān)聯(lián)?方案一陣亡。
方案二:在微信端授權(quán)后,以及在 PC 端注冊(cè)后“強(qiáng)制”要求用戶填寫手機(jī)號(hào)碼以此為關(guān)聯(lián)。這樣衍生出一個(gè)問題,必須確保用戶手機(jī)的真實(shí)信,沒問題。這個(gè)可以通過手機(jī)驗(yàn)證碼來實(shí)現(xiàn)(Email也是一樣)。但是不妨假設(shè)一下有下面這種情況,如果我有兩個(gè)手機(jī)號(hào)碼,PC 端注冊(cè)時(shí)填一個(gè),微信注冊(cè)時(shí)填另一個(gè)。關(guān)聯(lián)的了嗎?答案是很遺憾。再者,我在PC 端注冊(cè)后我就是不填(筆者把強(qiáng)制打上雙引號(hào)的原因),然后我用微信端授權(quán)登錄一下。好吧,此時(shí)將會(huì)有兩條數(shù)據(jù)等著你想辦法去關(guān)聯(lián),典型的開發(fā)者自挖坑。這種方式某種程度上行得通,但是嚴(yán)謹(jǐn)程度上是開發(fā)者無法接受的。
三、回歸原點(diǎn)的解決方案
分析:既然方案上述方案都有問題,我們先把它們都拋到一邊。整理一下思路,讓我們回到問題的根本。關(guān)聯(lián)的問題,要的是一個(gè)唯一標(biāo)識(shí)。唯一標(biāo)識(shí)正如我們的身份證號(hào)碼,我們辦理信用卡的時(shí)候身份證是必須的,實(shí)名制下購買號(hào)碼卡,身份證是必須的。假設(shè)我們是這系統(tǒng)管理員,那么我完全可以通過你的身份證號(hào)碼查出你手機(jī)號(hào)碼,銀行卡號(hào)碼。
有了上面的思路之后,我們需要做的就是找到一個(gè)唯一標(biāo)識(shí)來作為關(guān)聯(lián).微信上有個(gè)重要的角色 openid。 它跟我們上面提到的身份證號(hào)碼有這共同的作用,微信賬號(hào)對(duì)某一公眾號(hào)的唯一標(biāo)識(shí)。
微信端的授權(quán)拿到 openid 做過微信開發(fā)的人都應(yīng)該沒有問題。問題是怎樣來實(shí)現(xiàn) PC 端 在注冊(cè)或者登陸的時(shí)候拿到 openid。筆者的實(shí)現(xiàn)思路如下。PC 端注冊(cè),或者登陸時(shí)顯示一個(gè)二維碼引導(dǎo)用戶使用微信掃碼,使其跳轉(zhuǎn)到授權(quán)頁面。這一步有一個(gè)最為關(guān)鍵的細(xì)節(jié),二維碼請(qǐng)帶上一個(gè)唯一的授權(quán)碼(authCode)。試想一下如果用戶授權(quán)后我們能把 openid 以及 authCode 寫入到數(shù)據(jù)庫。那么我們就可以在 PC 端通過某個(gè) API 獲取 authCode 所關(guān)聯(lián)的這個(gè) openid。如果我們做到這點(diǎn)我們就可以知道當(dāng)前是誰在 PC 端進(jìn)行掃碼注冊(cè)或登錄(沒注冊(cè)的注冊(cè),有注冊(cè)的直接登錄)。 是不是突然覺得 so easy. 如果覺得文字比較抽象,請(qǐng)看下面圖示
PC 端微信掃碼登錄流程
核心代碼
搞清楚了思路和流程接下來我們直接上代碼啦.開發(fā)思路是共通的,開發(fā)語言就請(qǐng)各顯神通啦。
說明:下面代碼以 C# 語言為例,采用 MVC + EF (注:uuid 等價(jià)于我們上述的 authCode)
掃碼登錄頁后臺(tái)代碼
public ActionResult Login() { //如果已登錄,直接跳轉(zhuǎn)到首頁 if (User.Identity.IsAuthenticated) return RedirectToAction("Index", "Home"); string url = Request.Url.Host; string uuid = Guid.NewGuid().ToString(); ViewBag.url = "http://" + url + "/home/loginfor?uuid=" + uuid;//構(gòu)造授權(quán)鏈接 ViewBag.uuid = uuid;//保存 uuid return View(); }
生成二維碼采用插件 jquery.qrcode.js,想詳細(xì)了解的朋友請(qǐng)移步 Github。 這里需要注意的一點(diǎn)是,該插件可以指定二維碼的生成方式,canvas 或者 table 請(qǐng)需要支持 IE 的朋友指定使用 table 生成
代碼如下:
jQuery('#qrcode').qrcode({ render : "table", text : "http://baidu.com" });
回歸正題,登錄頁面的主要代碼如下
<!--生成二維碼的容器 div--> <div id="qrcode-container"> </div> <script src="~/Plugins/Jquery/jquery-1.9.1.min.js"></script> <script src="~/Plugins/jquery-qrcode/jquery.qrcode.min.js"></script> <script> jQuery(function () { //生成二維碼 jQuery('#qrcode-container').qrcode("@ViewBag.url"); //輪詢判斷用戶是否授權(quán) var interval = setInterval(function () { $.post("@Url.Action("UserLogin","Home")", { "uuid": "@ViewBag.uuid" }, function (data, status) { if ("success" == status) { //用戶成功授權(quán)=>跳轉(zhuǎn) if ("success" == data) { window.location.href = '@Url.Action("Index", "Home")'; clearInterval(interval); } } }); }, 200); }) </script>
輪詢判斷用戶是否授權(quán) API 代碼
public string UserLogin(string uuid) { //驗(yàn)證參數(shù)是否合法 if (string.IsNullOrEmpty(uuid)) return "param_error"; WX_UserRecord user = db.WX_UserRecord.Where(u => u.uuId == uuid).FirstOrDefault(); if (user == null) return "not_authcode"; //寫入cookie FormsAuthentication.SetAuthCookie(user.OpenId, false); //清空uuid user.uuId = null; db.SaveChanges(); return "success"; }
微信端授權(quán) Action
public ActionResult Loginfor(string uuid) { #region 獲取基本信息 - snsapi_userinfo /* * 創(chuàng)建微信通用類 - 這里代碼比較復(fù)雜不在這里貼出 * 遲點(diǎn)我會(huì)將整個(gè) Demo 稍微整理放上 Github */ WechatUserContext wxcontext = new WechatUserContext(System.Web.HttpContext.Current, uuid); //使用微信通用類獲取用戶基本信息 wxcontext.GetUserInfo(); if (!string.IsNullOrEmpty(wxcontext.openid)) { uuid = Request["state"]; //判斷數(shù)據(jù)庫是否存在 WX_UserRecord user = db.WX_UserRecord.Where(u => u.OpenId == wxcontext.openid).FirstOrDefault(); if (null == user) { user = new WX_UserRecord(); user.OpenId = wxcontext.openid; user.City = wxcontext.city; user.Country = wxcontext.country; user.CreateTime = DateTime.Now; user.HeadImgUrl = wxcontext.headimgurl; user.Nickname = wxcontext.nickname; user.Province = wxcontext.province; user.Sex = wxcontext.sex; user.Unionid = wxcontext.unionid; user.uuId = uuid; db.WX_UserRecord.Add(user); } user.uuId = uuid; db.SaveChanges(); } #endregion return View(); }
最后附上數(shù)據(jù)庫表設(shè)計(jì)
沒什么特殊的,就是微信返回的各個(gè)參數(shù)加多一個(gè)我們自定義的 uuId
微信參數(shù)說明 詳情請(qǐng)見 微信開發(fā)者文檔
運(yùn)行效果
1.掃碼登錄頁面
2.請(qǐng)求用戶授權(quán)
3.用戶確認(rèn)授權(quán)
4.PC 端登錄完成
文章難免有不足之處,還請(qǐng)海涵。如有發(fā)現(xiàn)錯(cuò)誤還望留言指出,筆者感激不盡! 微信掃碼注冊(cè)登錄 Demo 待筆者整理后放上 Github 希望幫到更多的朋友,請(qǐng)有需要的朋友留意該文更新。
以上就是PC 端微信掃碼注冊(cè)和登錄 的實(shí)例,有需要的朋友可以參考下,謝謝大家對(duì)本站的支持!
- 微信支付java版V3驗(yàn)證數(shù)據(jù)合法性(Deom)
- php微信公眾賬號(hào)開發(fā)之五個(gè)坑(二)
- nodejs微信公眾號(hào)支付開發(fā)
- php微信公眾賬號(hào)開發(fā)之前五個(gè)坑(一)
- MVC微信網(wǎng)頁授權(quán)獲取用戶OpenId
- ASP.NET MVC5+EF6+EasyUI后臺(tái)管理系統(tǒng) 微信公眾平臺(tái)開發(fā)之資源環(huán)境準(zhǔn)備
- 微信支付的開發(fā)流程詳解
- 微信公眾號(hào)可通過現(xiàn)金紅包接口發(fā)放微信支付現(xiàn)金紅包(附開發(fā)教程)
- PHP仿微信多圖片預(yù)覽上傳實(shí)例代碼
- 微信支付PHP SDK —— 公眾號(hào)支付代碼詳解
相關(guān)文章
Java網(wǎng)絡(luò)編程之TCP通信完整代碼示例
這篇文章主要介紹了Java網(wǎng)絡(luò)編程之TCP通信完整代碼示例,具有一定借鑒價(jià)值,需要的朋友可以了解下。2017-12-12解決Maven項(xiàng)目加載spring bean的配置xml文件會(huì)提示找不到問題
這篇文章主要介紹了解決Maven項(xiàng)目加載spring bean的配置xml文件會(huì)提示找不到問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-08-08Java?數(shù)據(jù)結(jié)構(gòu)與算法系列精講之漢諾塔
漢諾塔是源于印度一個(gè)古老傳說的益智玩具。大梵天創(chuàng)造世界時(shí)做了三根石柱,在一根柱子上從下往上按大小順序摞著64片黃金圓盤。大梵天命令婆羅門把圓盤從下面開始按大小順序重新擺放在另一根柱子上。并且規(guī)定,在小圓盤上不能放大圓盤,三根柱子之間一次只能移動(dòng)一個(gè)圓盤2022-02-02一篇文章帶你學(xué)習(xí)JAVA MyBatis底層原理
近來想寫一個(gè)mybatis的分頁插件,但是在寫插件之前肯定要了解一下mybatis具體的工作原理吧,本文就詳細(xì)總結(jié)了MyBatis工作原理,,需要的朋友可以參考下2021-09-09java基于servlet使用組件smartUpload實(shí)現(xiàn)文件上傳
這篇文章主要介紹了java基于servlet使用組件smartUpload實(shí)現(xiàn)文件上傳,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-10-10Springboot-admin整合Quartz實(shí)現(xiàn)動(dòng)態(tài)管理定時(shí)任務(wù)的過程詳解
Quartz是一款Java編寫的開源任務(wù)調(diào)度框架,同時(shí)它也是Spring默認(rèn)的任務(wù)調(diào)度框架,它的作用其實(shí)類似于Timer定時(shí)器以及ScheduledExecutorService調(diào)度線程池,這篇文章主要介紹了Springboot-admin整合Quartz實(shí)現(xiàn)動(dòng)態(tài)管理定時(shí)任務(wù),需要的朋友可以參考下2023-04-04