微信扫码登陆
微信扫码登陆网站,且与小程序打通。
1.申请微信开放平台网站应用。
2.你需要Appid和secret
3.设置你的回调域名。是回调域名,不是回调方法地址
4.申请好了之后就可以写代码啦
4.1.获取二维码。按照官方文档,有两种方式,一种是后台获取,返回一个html。另一种是前端js获取。现在我们主要说后台获取
/// <summary> /// 扫码登陆请求 /// 第一步获取返回的code /// </summary> [HttpGet] public void ScanLogin() { BaseBLL<weixin_open> bll = new BaseBLL<weixin_open>(); var weixin_open = bll.Find(o => o.appid != null && o.secret != null); string appid = weixin_open.appid; string secret = weixin_open.secret; string server = Util.getServerPath(); string redirect_uri = System.Web.HttpUtility.UrlEncode("扫码成功后跳转的页面,需要此页面调用获取下一步获取access_token和用户信息的方法"); LogHelper.Info("redirect_uri:" + redirect_uri); string state = sys.getRandomCode(16);//随机生成 //缓存state HttpContext.Current.Session["weixin_login_state"] = state; WeixinOpenAPI api = new WeixinOpenAPI(appid, secret); LogHelper.Info(api.GetCode("登陆的code:" + redirect_uri, state)); string result = api.GetCode(redirect_uri, state); result = result.Replace("/connect/qrcode/", "https://open.weixin.qq.com/connect/qrcode/"); HttpContext.Current.Response.Write(result); HttpContext.Current.Response.End(); }
/// <summary> /// 第一步:请求CODE /// </summary> /// <param name="redirect_uri">回调域名</param> /// <param name="state"></param> public string GetCode(string redirect_uri,string state) { string url = "https://open.weixin.qq.com/connect/qrconnect?appid=" + appid + "&redirect_uri=" + redirect_uri + "&response_type=code&scope=snsapi_login&state=" + state + "#wechat_redirect"; string s = Util.MethodGET(url); return s; }
调用结果
4.2.扫码成功后会调到回调页,在回调页面请求access_token与openid
/// <summary> /// 回调函数 /// </summary> /// <param name="code">请求微信返回的code</param> /// <param name="state">请求微信的参数state</param> /// <returns></returns> public ApiResult LoginReturn(string code, string state) { ApiResult apiResult = new ApiResult(); LogHelper.Info("code:" + code + ",state:" + state); //必须用cookie或者session var session = HttpContext.Current.Session["weixin_login_state"]; string session_state = session == null ? "" : session.ToString(); if (state == _state) { BaseBLL<weixin_open> bll = new BaseBLL<weixin_open>(); var weixin_open = bll.Find(o => o.appid != null && o.secret != null); string appid = weixin_open.appid; string secret = weixin_open.secret; WeixinOpenAPI api = new WeixinOpenAPI(appid, secret); api.GetAccessToken(code); LogHelper.Info("access_token:" + api.access_token); string user_json = api.GetUserInfo(api.openid); LogHelper.Info("user_json:" + user_json); JObject obj = JObject.Parse(user_json); string openid = obj["openid"] == null ? "" : obj["openid"].ToString(); LogHelper.Info("openid:" + openid); BaseBLL<weixin_applet> weixinAppletBll = new BaseBLL<weixin_applet>(); weixin_applet weixinApplet = weixinAppletBll.Find(x => x.appcode == "ZHIYIN"); weixin_user userInfo = new weixin_user { openid = obj["openid"] == null ? "" : obj["openid"].ToString(), unionid = obj["unionid"] == null ? "" : obj["unionid"].ToString(), nickname = obj["nickname"] == null ? "" : obj["nickname"].ToString(), sex = obj["sex"] == null ? 0 : int.Parse(obj["sex"].ToString()), language = obj["language"] == null ? "" : obj["language"].ToString(), city = obj["city"] == null ? "" : obj["city"].ToString(), province = obj["province"] == null ? "" : obj["province"].ToString(), country = obj["country"] == null ? "" : obj["country"].ToString(), headimgurl = obj["headimgurl"] == null ? "" : obj["headimgurl"].ToString(), source_code = weixinApplet.appcode, weixin_applet_id = weixinApplet.id }; if (!Util.isNotNull(openid)) { return new ApiResult() { success = false, message = "openid为空" }; } #region 微信登陆,保存信息 //如果不存在则要创建,创建时,先创建 iuser ,再创建 weixin_user bool first_login = false; BaseBLL<weixin_user> weixinUserBll = new BaseBLL<weixin_user>(); if (Util.isNotNull(userInfo.unionid)) { var weixinUser = weixinUserBll.Find(o => o.unionid == userInfo.unionid); //可能是第一次登陆,在网页端登陆 if (weixinUser == null) { first_login = true; //先存iuser var iuser = new iuser(); BaseBLL<iuser> iuserBll = new BaseBLL<iuser>(); iuser.random = sys.getRandomStr(); iuser.createtime = DateTime.Now; iuser.updatetime = DateTime.Now; iuser = iuserBll.Add(iuser); //再存weixin_user userInfo.uid = iuser.id; userInfo.sub_time = DateTime.Now; userInfo.first_sub_time = DateTime.Now; LogHelper.Info("first_login:" + first_login + ",userInfo:" +Newtonsoft.Json.JsonConvert.SerializeObject(userInfo)); weixinUser = weixinUserBll.Add(userInfo); } else { weixinUser.nickname = userInfo.nickname; weixinUser.headimgurl = userInfo.headimgurl; LogHelper.Info("first_login:" + first_login + ",userInfo:" + Newtonsoft.Json.JsonConvert.SerializeObject(userInfo)); weixinUserBll.Update(weixinUser); } apiResult.success = true; apiResult.data = new { first_login = first_login, weixinUser = weixinUser }; apiResult.status = ApiStatusCode.OK; } else { return new ApiResult() { success = false, message = "微信开发平台未获取到unionid" }; } #endregion } else { return new ApiResult() { success = false, message = "请求超时" }; } return apiResult; }
/// <summary> /// 第二步:获取access_token /// </summary> /// <param name="code"></param> /// <returns></returns> public void GetAccessToken(string code) { string s = Util.MethodGET("https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + appid + "&secret=" + secret + "&code=" + code + "&grant_type=authorization_code", "UTF-8"); try { LogHelper.Info("code换取access_token:" + s); JObject jo = JObject.Parse(s); access_token = jo["access_token"].ToString(); access_token_time = System.DateTime.Now.AddSeconds(double.Parse(jo["expires_in"].ToString())).ToString(); refresh_token = jo["refresh_token"].ToString(); openid = jo["openid"].ToString(); } catch (Exception e) { LogHelper.Error("获取微信开发平台access_token失败:" + e.Message); } }
/// <summary> /// 第三步:获取用户信息 /// </summary> /// <returns></returns> public string GetUserInfo(string openid) { string url = "https://api.weixin.qq.com/sns/userinfo?access_token="+access_token+"&openid="+openid; return Util.MethodGET(url, "UTF-8"); }
如此如此,这般这般就算是完了
纸上得来终觉浅,绝知此事要躬行