微信认证登录
最近为公司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 }
显示效果
学无先后,达者为师