官方api:https://developers.weixin.qq.com/miniprogram/dev/api/api-login.html#wxloginobject

参考文章:https://zhuanlan.zhihu.com/p/25124713

微信小程序API文档:开放接口 · 小程序
在实际的小程序开发中,往往需要用户授权登陆并获取用户的数据,快速对接用户系统。
openId : 用户在当前小程序的唯一标识
unionId : 如果开发者拥有多个移动应用、网站应用、和公众帐号(包括小程序),可通过unionid来区分用户的唯一性,因为只要是同一个微信开放平台帐号下的移动应用、网站应用和公众帐号(包括小程序),用户的unionid是唯一的。换句话说,同一用户,对同一个微信开放平台下的不同应用,unionId是相同的。详情登录微信开放平台(http://open.weixin.qq.com) 。
在微信小程序开发中,unionId等敏感数据则被加密在encryptedData,于是需要以下流程来解密敏感数据,从而获取unionId等信息。
流程
1、(客户端)微信小程序客户端调用 wx.login()接口获取登录凭证(code)

//1、调用微信登录接口,获取code
wx.login({
    success: function (r) {
        var code = r.code;//登录凭证
        if (code) {
            //2、调用获取用户信息接口
            //...

        } else {
            console.log('获取用户登录态失败!' + r.errMsg)
        }
    },
    fail: function () {
        callback(false)
    }
})
2、(客户端)微信小程序客户端调用 wx.getUserInfo()接口获取 用户基本信息、encryptedData(用户敏感信息加密数据) 和 iv(加密算法的初始向量 )

//1、调用微信登录接口,获取code
wx.login({
    success: function (r) {
        var code = r.code;//登录凭证
        if (code) {
            //2、调用获取用户信息接口
            wx.getUserInfo({
                success: function (res) {
                    console.log({encryptedData: res.encryptedData, iv: res.iv, code: code})
                    //3.解密用户信息 获取unionId
                    //...
                },
                fail: function () {
                    console.log('获取用户信息失败')
                }
            })

        } else {
            console.log('获取用户登录态失败!' + r.errMsg)
        }
    },
    fail: function () {
        callback(false)
    }
})
3、(客户端)将前面获取到的 code 、encryptedData、iv发送到自己的服务器(开发者服务器),通过自己的服务器(开发者服务器)解密获取信息

//1、调用微信登录接口,获取code
wx.login({
    success: function (r) {
        var code = r.code;//登录凭证
        if (code) {
            //2、调用获取用户信息接口
            wx.getUserInfo({
                success: function (res) {
                    console.log({encryptedData: res.encryptedData, iv: res.iv, code: code})
                    //3.请求自己的服务器,解密用户信息 获取unionId等加密信息
                    wx.request({
                        url: 'https://xxxx.com/wxsp/decodeUserInfo',//自己的服务接口地址
                        method: 'post',
                        header: {
                            'content-type': 'application/x-www-form-urlencoded'
                        },
                        data: {encryptedData: res.encryptedData, iv: res.iv, code: code},
                        success: function (data) {

                            //4.解密成功后 获取自己服务器返回的结果
                            if (data.data.status == 1) {
                                var userInfo_ = data.data.userInfo;
                                console.log(userInfo_)
                            } else {
                                console.log('解密失败')
                            }

                        },
                        fail: function () {
                            console.log('系统错误')
                        }
                    })
                },
                fail: function () {
                    console.log('获取用户信息失败')
                }
            })

        } else {
            console.log('获取用户登录态失败!' + r.errMsg)
        }
    },
    fail: function () {
         console.log('登陆失败')
    }
})
4、(服务端 java)自己的服务器发送code到微信服务器获取openid(用户唯一标识)和session_key(会话密钥),最后将encryptedData、iv、session_key通过AES解密获取到用户敏感数据

a、获取秘钥并处理解密的controller(这里用的是springMVC)

/**
     * 解密用户敏感数据
     *
     * @param encryptedData 明文,加密数据
     * @param iv            加密算法的初始向量
     * @param code          用户允许登录后,回调内容会带上 code(有效期五分钟),开发者需要将 code 发送到开发者服务器后台,使用code 换取 session_key api,将 code 换成 openid 和 session_key
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/decodeUserInfo", method = RequestMethod.POST)
    public Map decodeUserInfo(String encryptedData, String iv, String code) {

        Map map = new HashMap();

        //登录凭证不能为空
        if (code == null || code.length() == 0) {
            map.put("status", 0);
            map.put("msg", "code 不能为空");
            return map;
        }

        //小程序唯一标识   (在微信小程序管理后台获取)
        String wxspAppid = "xxxxxxxxxxxxxx";
        //小程序的 app secret (在微信小程序管理后台获取)
        String wxspSecret = "xxxxxxxxxxxxxx";
        //授权(必填)
        String grant_type = "authorization_code";

        //////////////// 1、向微信服务器 使用登录凭证 code 获取 session_key 和 openid ////////////////
        //请求参数
        String params = "appid=" + wxspAppid + "&secret=" + wxspSecret + "&js_code=" + code + "&grant_type=" + grant_type;
        //发送请求
        String sr = HttpRequest.sendGet("https://api.weixin.qq.com/sns/jscode2session", params);
        //解析相应内容(转换成json对象)
        JSONObject json = JSONObject.fromObject(sr);
        //获取会话密钥(session_key)
        String session_key = json.get("session_key").toString();
        //用户的唯一标识(openid)
        String openid = (String) json.get("openid");

        //////////////// 2、对encryptedData加密数据进行AES解密其中包含这openid和unionid ////////////////
        try {
            String result = AesCbcUtil.decrypt(encryptedData, session_key, iv, "UTF-8");
            if (null != result && result.length() > 0) {
                map.put("status", 1);
                map.put("msg", "解密成功");

                JSONObject userInfoJSON = JSONObject.fromObject(result);
                Map userInfo = new HashMap();
                userInfo.put("openId", userInfoJSON.get("openId"));
                userInfo.put("nickName", userInfoJSON.get("nickName"));
                userInfo.put("gender", userInfoJSON.get("gender"));
                userInfo.put("city", userInfoJSON.get("city"));
                userInfo.put("province", userInfoJSON.get("province"));
                userInfo.put("country", userInfoJSON.get("country"));
                userInfo.put("avatarUrl", userInfoJSON.get("avatarUrl"));
                userInfo.put("unionId", userInfoJSON.get("unionId"));
                map.put("userInfo", userInfo);
                return map;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        map.put("status", 0);
        map.put("msg", "解密失败");
        return map;
    }

小程序获取openid和unionid java实现的更多相关文章

  1. C# 微信小程序获取openid sessionkey

    项目介绍 1.微信小程序获取openid和session_key 2.后台使用C#开发 项目流程 准备工作 1 获取appid 1.1 下载微信web开发工具 https://developers.w ...

  2. 微信中的APP、公众号、小程序的openid及unionid介绍

    微信中的APP.公众号.小程序的openid及unionid介绍 1.unionid 如果开发者拥有多个移动应用.网站应用.和公众帐号(包括小程序),可通过 UnionID 来区分用户的唯一性,因为只 ...

  3. 小程序获取openid 小程序授权

    小程序获取openid 小程序可以通过微信官方提供的登录能力方便地获取微信提供的用户身份标识,快速建立小程序内的用户体系. wx.login(Object object) 调用接口获取登录凭证(cod ...

  4. 小程序获取openId

    1.小程序获取微信openId   wx.login({ success: res => { // 发送 res.code 到后台换取 openId, sessionKey, unionId / ...

  5. 微信小程序 获取OpenId

    微信小程序 官方API:https://mp.weixin.qq.com/debug/wxadoc/dev/api/ 首先 以下代码是 页面加载请求用户 是否同意授权 同意之后 用code 访问 微信 ...

  6. 微信小程序——获取openid

    1.在微信小程序后台得到appid.AppSecret 2.在任意小程序界面的[onLoad]中取得code(建议将代码写在index.js中) 3.用取得code换取openid 如后台无法将ope ...

  7. .NET开发微信小程序-获取OpenId

    注:获取当前用户信息只需要用GetUserInfo这个方法就行.这里就不需要提了 前端代码: CallBack:回调函数 function GetOpenID(CallBack){ var appIn ...

  8. 小程序获取 openid 和 session_key

    <?php //获取openid function getopenid(){//获取用户ID //code为前端通过 wx.login() 方式获取 $code = $_GET["co ...

  9. PHP 微信公众号/小程序获取openid,用户信息

    1.获取code (获得openid的前置条件) 地址:https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redi ...

随机推荐

  1. TCP/IP详解 卷一(第十七章 TCP:传输控制协议)

    与UDP协议相比,TCP提供一种面向连接的.可靠的字节流服务. TCP首部 跟UDP一样,TCP数据被封装在一个IP数据报中,下面显示TCP的首部数据格式 每个TCP段都包含源端和目的端的端口号,用于 ...

  2. 如何手动编译运行带包 java 程序

    带包的java程序比普通java程序的编译稍微复杂一些.例如下面的例子: package cn.guopeng; import java.util.*; public class hello { pu ...

  3. smali语法高亮相关链接

    http://ruby-china.org/topics/8307 http://www.daqianduan.com/4820.html http://www.cnblogs.com/ruochen ...

  4. Swing基础知识

    1 http://zxc8899.iteye.com/blog/1556094  最基本的组件 2 http://zhangjunhd.blog.51cto.com/113473/128174 布局管 ...

  5. 【hadoop之翊】——windows 7使用eclipse下hadoop应用开发环境搭建

    由于一些缘故,这节内容到如今才写.事实上弄hadoop有一段时间了,能够编写一些小程序了,今天来还是来说说环境的搭建.... 说明一下:这篇文章的步骤是接上一篇的hadoop文章的:http://bl ...

  6. 安装MacOS到虚拟机

    [TOC] 系统版本历史 4. 升级系统到10.12.6版本 时间:2017年9月21日 15:58:55 大小:VMDK(7.63 GB) 变动: 升级系统到10.12.6版本 3. 降低内存到6G ...

  7. macOS 安装安卓模拟器 并用charles抓包

    mac上面安装安卓模拟器并能使用charles抓包软件调研 一.Genymotion 1.先下载Virtua Box虚拟机 https://www.virtualbox.org/wiki/Downlo ...

  8. java -cp 命令 java jar 命令和 hadoop jar 命令

     -cp 和 -classpath 一样,是指定类运行所依赖其他类的路径,通常是类库,jar包之类,需要全路径到jar包,window上分号“;”  java -cp .;myClass.jar pa ...

  9. window 杀死已开任务启命令

    1. 查询已开启的端口号 C:\Users\Administrator>netstat -ano | findstr 如果被占用会查询出相关信息,如果没有被占用则不会输出任何信息,查询到已开启信 ...

  10. SQL索引及表的页的逻辑顺序与物理顺序

    1.经过测试发现当聚集索引新建或者重建时,会按照逻辑顺序重新排列数据页和数据页内的数据行的物理顺序. 2.但修改表时,无论是聚集索引还是堆的数据页都是按自然顺序向后插入数据,页面上的偏移量可以证明.因 ...