zoukankan      html  css  js  c++  java
  • unity探索者之安卓微信登录,非第三方插件

    版权声明:本文为原创文章,转载请声明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();
        }
    View Code

    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发送给服务端就好

  • 相关阅读:
    java中的HMAC-SHA1加密
    java拦截处理System.exit(0)
    使用canal分析binlog(二) canal源码分析
    JS的异步世界
    socket.io的用户认证
    一个补零小函数
    使用gulp在开发过程中合理导出zip文件
    使用r.js进行前端repuirejs的合并压缩
    使用r2d3的注意事项
    三列自适应布局的实现方式(兼容IE6+)
  • 原文地址:https://www.cnblogs.com/unityExplorer/p/7666348.html
Copyright © 2011-2022 走看看