一、(客戶端)微信小程序客戶端調用 wx.login()接口獲取登陸憑證(code)html
//一、調用微信登陸接口,獲取code wx.login({ success: function (r) { var code = r.code;//登陸憑證 if (code) { //二、調用獲取用戶信息接口 //... } else { console.log('獲取用戶登陸態失敗!' + r.errMsg) } }, fail: function () { callback(false) } })
二、(客戶端)微信小程序客戶端調用 wx.getUserInfo()接口獲取 用戶基本信息、encryptedData(用戶敏感信息加密數據) 和 iv(加密算法的初始向量 )java
//一、調用微信登陸接口,獲取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) } })
三、(客戶端)將前面獲取到的 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('登錄失敗') } })
四、(服務端 java)本身的服務器發送code到微信服務器獲取openid(用戶惟一標識)和session_key(會話密鑰),最後將encryptedData、iv、session_key經過AES解密獲取到用戶敏感數據spring
a、獲取祕鑰並處理解密的controller(這裏用的是springMVC)apache
/** * 解密用戶敏感數據 * * @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解密 //////////////// 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