最近為公司OA系統添加了新的功能---微信驗證登錄,即用戶輸入賬號密碼后賬號驗證通過即跳轉微信二維碼掃描認證。之前並沒有接觸過微信開發,后瀏覽微信開放平台接口,研究一番后感覺應該可以搞定,但是開放平台需要提交《微信開放平台網站信息登記表》據說官方審核還需4到7個工作日,后續研究了解到公眾號可以實現微信驗證登錄,公司公眾號已綁定微商城回調地址,於是與開發微商城同事商量在他的項目中添加頁面返回code.
具體接口大家可以查看官方提供的API上面介紹很清楚,下面介紹我的實現過程。
1.數據庫驗證用戶名密碼。
2.驗證通過跳轉微信驗證頁面,根據回調域名和跳轉鏈接生成二維碼。
1 string uuid = Guid.NewGuid().ToString(); 2 string host = System.Web.HttpContext.Current.Request.Url.Host; 3 string path = "/manage/WeChatAuthorize?uuid=" + uuid + "&uid=" + model.UserID;//這是oa系統頁面用於接收code 記錄了guid,便於驗證 4 string redirect_uri = HttpUtility.UrlEncode("http://" + host + path);//注意必須使用UrlEncode編碼 5 string AuthorizeUrl = "http://*******.com/wechat/get-wechat-code?returnUrl=" + redirect_uri; //微信授權鏈接 get-wechat-code頁面放在和公眾號配置的回調域名一個目錄下,頁面主要邏輯是根據APPID返回code並跳轉到調用頁面(redirect_uri), 主域名須和跳轉頁面所在主域一致
Session["uuid"] = uuid;//保存 guid
get-wechat-code頁面邏輯(該頁面在php微商城項目中,這兒大體用.net說明邏輯)
1 string redirect_uri = Request.redirect_uri; 2 WeChatData data = new WeChatData(); 3 data.SetValue("appid", WeChatConfig.APPID); 4 data.SetValue("redirect_uri", redirect_uri); 5 data.SetValue("response_type", "code"); 6 data.SetValue("scope", "snsapi_userinfo"); 7 data.SetValue("state", state + "#wechat_redirect"); 8 string url = "https://open.weixin.qq.com/connect/oauth2/authorize?" + data.ToUrl(); 9 try 10 { 11 //觸發微信返回code碼 12 currentHttpContext.Response.Redirect(url);//重定向到redirect_uri頁面 13 } 14 catch (System.Threading.ThreadAbortException ex) 15 { 16 }
3.回調頁面根據code參數返回openid,並保存openid、uuid、uid到數據庫
1 //根據返回code碼獲取openid和access_token 2 string code = currentHttpContext.Request.QueryString["code"]; 3 4 #region [根據code返回openid] 5 WeChatData data = new WeChatData(); 6 data.SetValue("appid", WeChatConfig.APPID); 7 data.SetValue("secret", WeChatConfig.APPSECRET); 8 data.SetValue("code", code); 9 data.SetValue("grant_type", "authorization_code"); 10 string url = "https://api.weixin.qq.com/sns/oauth2/access_token?" + data.ToUrl(); 11 //請求url以獲取數據 12 string result = HttpService.Get(url); 13 //保存access_token,用於收貨地址獲取 14 JsonData jd = JsonMapper.ToObject(result); 15 access_token = (string)jd["access_token"]; 16 //獲取用戶openid 17 openid = (string)jd["openid"]; 18 #endregion
1 #region [用戶基本信息] 2 string user_info_api = "https://api.weixin.qq.com/sns/userinfo?access_token=" + this.access_token + "&openid=" + openid + "&lang=zh_CN"; 3 string result = HttpService.Get(user_info_api); 4 JsonData jd = JsonMapper.ToObject(result); 5 nickname = (string)jd["nickname"]; 6 sex = (int)jd["sex"]; 7 province = (string)jd["province"]; 8 city = (string)jd["city"]; 9 country = (string)jd["country"]; 10 headimgurl = (string)jd["headimgurl"]; 11 #endregion
1 #region [保存openid+用戶信息+登錄賬號+uuid] 2 //代碼略 3 //主要邏輯 4 user = dbContext.oa_wechat_emp.Where(u => u.uid == uid || u.openid==weChatUserInfo.openid).FirstOrDefault(); 5 //如果賬號已存在判斷openid是否一致,如果一致更新uuid 6 if (user != null) 7 { 8 if (user.openid == weChatUserInfo.openid&&uid==user.uid) 9 user.uuId = uuid;//關鍵步驟 前后台驗證 10 else 11 { 12 isValidStr = "登錄失敗"; 13 isValid = 0;//驗證失敗 14 } 15 } 16 else 17 { 18 //保存新數據 19 } 20 #endregion
4.前台輪詢驗證 根據uuid驗證 上一步驟已經明確如果數據存在會更新uuid而這個uuid自始至終前后台是一致的
1 //輪詢判斷用戶是否授權 2 var interval = setInterval(function () { 3 $.post("@Url.Action("CheckAuthorizedWeChatUser", "Manage")", { "uuid": "@ViewBag.uuid" }, function (r) { 4 if ("success" == r.status) { 5 //用戶成功授權=>跳轉 6 if ("success" == r.data) { 7 clearInterval(interval); 8 window.location.href = '@Url.Action("Index", "Manage")'; 9 } 10 } 11 }); 12 }, 2000);
CheckAuthorizedWeChatUser方法:
1 //驗證參數是否合法 2 using (OAEntities dbContext = new OAEntities()) 3 { 4 oa_wechat_emp user = dbContext.oa_wechat_emp.Where(u => u.uuId == uuid).FirstOrDefault(); 5 if (user == null) 6 return Json(new { status = "success", data = "wrong_validate" }); 7 else 8 { 9 hr_model = dbContext.hr_employee.Where(t => t.uid == user.uid).FirstOrDefault(); 10 } 11 }
顯示效果