

官方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) //一、调用微信登陆接口,获取code
wx.login({ success: function (r) { var code = r.code;//登陆凭证
if (code) { //二、调用获取用户信息接口 //...
} else { console.log('获取用户登陆态失败!' + r.errMsg) } }, fail: function () { callback(false) } }) 2、(客户端)微信小程序客户端调用 wx.getUserInfo()接口获取 用户基本信息、encryptedData(用户敏感信息加密数据) 和 iv(加密算法的初始向量 ) //一、调用微信登陆接口,获取code
wx.login({ success: function (r) { var code = r.code;//登陆凭证
if (code) { //二、调用获取用户信息接口
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发送到本身的服务器(开发者服务器),经过本身的服务器(开发者服务器)解密获取信息 //一、调用微信登陆接口,获取code
wx.login({ success: function (r) { var code = r.code;//登陆凭证
if (code) { //二、调用获取用户信息接口
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"; //////////////// 一、向微信服务器 使用登陆凭证 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"); //////////////// 二、对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; }