当前位置: 首页 > news >正文

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

 

转载于:https://www.cnblogs.com/unityExplorer/p/7666348.html

相关文章:

  • json 解析豆瓣ApiURL
  • mongodb数据备份脚本和日志切割脚本
  • 资讯丨Linux基金会一行到访腾讯参观交流
  • 《设计模式之禅》--代理扩展:动态代理
  • IOLI-crackme0x01-0x05 writeup
  • 思考|自动化测试面试题第一波
  • 算法学习之路|欧拉回路初见
  • python3 _笨方法学Python_日记_DAY1
  • 猫头鹰的深夜翻译:JDK9 NotNullOrElse方法
  • 提高开发效率之VS Code基础配置篇
  • 【301】IDL与C#混合编程
  • 小总结
  • 【18】万魂杀服务器开发之SDK接入
  • 12c broker fast-start failover - ORA-16820解决
  • Nginx配置——区分PC或手机访问不同域名
  • 【每日笔记】【Go学习笔记】2019-01-10 codis proxy处理流程
  • 07.Android之多媒体问题
  • 0x05 Python数据分析,Anaconda八斩刀
  • 2017年终总结、随想
  • in typeof instanceof ===这些运算符有什么作用
  • Linux链接文件
  • Perseus-BERT——业内性能极致优化的BERT训练方案
  • Promise面试题,控制异步流程
  • react-native 安卓真机环境搭建
  • vue-loader 源码解析系列之 selector
  • 第三十一到第三十三天:我是精明的小卖家(一)
  • 电商搜索引擎的架构设计和性能优化
  • 分享一个自己写的基于canvas的原生js图片爆炸插件
  • 一文看透浏览器架构
  • 在GitHub多个账号上使用不同的SSH的配置方法
  • AI算硅基生命吗,为什么?
  • Hibernate主键生成策略及选择
  • 从如何停掉 Promise 链说起
  • 小白应该如何快速入门阿里云服务器,新手使用ECS的方法 ...
  • #使用清华镜像源 安装/更新 指定版本tensorflow
  • #我与Java虚拟机的故事#连载09:面试大厂逃不过的JVM
  • (C++17) optional的使用
  • (顶刊)一个基于分类代理模型的超多目标优化算法
  • (考研湖科大教书匠计算机网络)第一章概述-第五节1:计算机网络体系结构之分层思想和举例
  • (四) 虚拟摄像头vivi体验
  • (五)c52学习之旅-静态数码管
  • (译)计算距离、方位和更多经纬度之间的点
  • (转载)虚函数剖析
  • ***php进行支付宝开发中return_url和notify_url的区别分析
  • .[hudsonL@cock.li].mkp勒索病毒数据怎么处理|数据解密恢复
  • .MSSQLSERVER 导入导出 命令集--堪称经典,值得借鉴!
  • .NET C#版本和.NET版本以及VS版本的对应关系
  • .NET Framework 4.6.2改进了WPF和安全性
  • .net 使用ajax控件后如何调用前端脚本
  • .NetCore项目nginx发布
  • .NET的微型Web框架 Nancy
  • .net实现头像缩放截取功能 -----转载自accp教程网
  • .NET中使用Protobuffer 实现序列化和反序列化
  • .Net转Java自学之路—SpringMVC框架篇六(异常处理)
  • @四年级家长,这条香港优才计划+华侨生联考捷径,一定要看!