版权声明:本文为原创文章,转载请声明http://www.cnblogs.com/unityExplorer/p/7666348.html
之前写了两篇关于微信分享的博客,其实微信登录、分享、支付博主是一起做的,可惜太忙,一直没时间补上剩下的登录和支付,现在总算是有点时间把这俩内容补上了,先说登录吧。
unity接入微信的登录流程相对分享而言要麻烦些,流程如下:
向微信发起授权 - 微信返回授权信息 - 发送Get请求获取用户信息 - 将openid等用户信息发送至服务器 - 服务器返回登录结果
1、向微信发起请求
/** * 登录微信,为了工具的通用性,此处的state * 从unity传入,目前传入的值为固定的"app_wechat" * 正式使用建议改为随机数加session来校验 */ public static void LoginWeChat(String state) { // 发送授权登录信息,来获取code SendAuth.Req req = new SendAuth.Req(); // 设置应用的作用域,获取个人信息 req.scope = "snsapi_userinfo"; req.state = state; api.sendReq(req); }
2、处理微信回调,方式和微信分享相同,具体参考http://www.cnblogs.com/unityExplorer/p/7574561.html
@Override public void onResp(BaseResp resp) { switch (resp.getType()){ case 1://授权 if(resp.errCode == BaseResp.ErrCode.ERR_OK){ WechatLogin.GetOpenId("APP_ID", "APP_SECRET",((SendAuth.Resp) resp).code); } break; case 2://分享 UnityPlayer.UnitySendMessage("ShareManager", "WechatCallBack", "" + resp.errCode); break; } finish(); }
3、授权成功后,拿到微信返回的code,然后向微信发送get请求,获取微信登录授权口令,也就是access_token,最后再使用获取到的access_token和openid向微信请求用户数据
// 获取微信登录授权口令 public static void GetOpenId(String appId, String appSecret, String code) { SendGet("https://api.weixin.qq.com/sns/oauth2/access_token","appid=" + appId + "&secret=" + appSecret+ "&code=" + code + "&grant_type=authorization_code",1); } //发送Get请求获取用户信息 private static void GetUserInfo(String access_token, String openid) { SendGet("https://api.weixin.qq.com/sns/userinfo","access_token=" + access_token +"&openid=" + openid, 2); } private static void SendGet(final String url, final String param, final int type) { //创建异步的Get请求 AsyncTask<Object, Object, String> task = new AsyncTask<Object, Object, String>() { @Override protected String doInBackground(Object... params) { String result = ""; BufferedReader in = null; try { String urlNameString = url + "?" + param; URL realUrl = new URL(urlNameString); // 打开和URL之间的连接 URLConnection connection = realUrl.openConnection(); // 设置通用的请求属性 connection.setRequestProperty("accept", "*/*"); connection.setRequestProperty("connection", "Keep-Alive"); connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); // 建立实际的连接 connection.connect(); // 定义 BufferedReader输入流来读取URL的响应 in = new BufferedReader(new InputStreamReader( connection.getInputStream())); String line; while ((line = in.readLine()) != null) { result += line; } } catch (Exception e) { System.out.println("发送GET请求出现异常!" + e); e.printStackTrace(); } // 使用finally块来关闭输入流 finally { try { if (in != null) { in.close(); } } catch (Exception e2) { e2.printStackTrace(); } } return result; } @Override protected void onPostExecute(String info) { switch (type) { case 1: try { JSONObject jsStr = new JSONObject(info); access_token = jsStr.getString("access_token"); String openId = jsStr.getString("openid"); GetUserInfo(access_token, openId); } catch (Exception e) { UnityPlayer.UnitySendMessage("ThirdPartySdkManager", "LoginCallBack", ""); } break; case 2: try { JSONObject jsStr2 = new JSONObject(info); jsStr2.put("access_token",access_token); UnityPlayer.UnitySendMessage("ThirdPartySdkManager", "LoginCallBack", jsStr2.toString()); } catch (Exception e) { UnityPlayer.UnitySendMessage("ThirdPartySdkManager", "LoginCallBack", ""); } break; } } }; task.execute(); }
4、处理用户信息并登录
/// <summary> 微信登录回调 </summary> public void LoginCallBack(string callBackInfo) { //openid 普通用户的标识,对当前开发者帐号唯一 //nickname 普通用户昵称 //sex 普通用户性别,1为男性,2为女性 //province 普通用户个人资料填写的省份 //city 普通用户个人资料填写的城市 //country 国家,如中国为CN //headimgurl 用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空 //privilege 用户特权信息,json数组,如微信沃卡用户为(chinaunicom) //unionid 用户统一标识。针对一个微信开放平台帐号下的应用,同一用户的unionid是唯一的。多app数据互通保存该值 //access_token 用户当前临时token值,自主添加的值 if (!string.IsNullOrEmpty(callBackInfo)) { JsonData jd = JsonMapper.ToObject(callBackInfo); if (!string.IsNullOrEmpty(jd.TryGetString("errcode"))) { TipManager.Instance.OpenTip(TipType.SimpleTip, "登录失败,请重新授权"); LoadingNode.CloseLoadingNode(); return; } LoginPage lp = PageManager.Instance.GetPage<LoginPage>(); lp.Login(jd.TryGetString("unionid"), jd.TryGetString("openid"), jd.TryGetString("access_token"), jd.TryGetString("nickname") , int.Parse(jd.TryGetString("sex")), jd.TryGetString("headimgurl")); } else TipManager.Instance.OpenTip(TipType.SimpleTip, "登录失败,请重新授权"); }
在实际项目中,处于安全性考虑,可能会有将获取用户信息的步骤放到服务端上的需求,对于这种情况,只要将第3步的第二个阶段和第4步解析去掉,直接将code发送给服务端就好