背景
公司某平台管理中涉及微信小程序的数据操作,期间交互不流畅导致进度延缓,为此研究了一下微信小程序的开发.。此博文主要记录登录过程中的用户信息获取(如:手机号等),特此纪要!
问题
https://developers.weixin.qq.com/miniprogram/dev/framework/
上面的地址是小程序开发的官方文档,可以在其中下载微信小程序的开发工具,一键式安装后输入appId,(如果是其他人申请的开发账号,需要把自己的微信添加到开发组中),选择不使用云开发的另外一项,新建即可开始微信小程序的开发。
说明
目前来说官方给的接口文档相对来说用心细品都是能够实现相应接口的开发.
纪要
下面开始登录用户信息处理的相关代码介绍:
<!-- 需要将 button 组件 open-type 的值设置为 getPhoneNumber,当用户点击并同意之后,可以通过 bindgetphonenumber 事件回调获取到微信服务器返回的加密数据, 然后在第三方服务端结合 session_key 以及 app_id 进行解密获取手机号。--> <button open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber">xxxxx</button>
getPhoneNumber: function(data) { // 登录 wx.login({ success: function(loginSucess){ var code = loginSucess.code; if(code){ wx.getUserInfo({ withCredentials:true,//非必填 默认为true success:function(infoRes){ console.log(infoRes.encryptedData); wx.request({ url: 'http://localhost/dev-api/login', method: "post", data: { from:"wechat", code:loginSucess.code,//临时登录凭证 "rawData":infoRes.rawData,//用户非敏感信息 "signature":infoRes.signature,//签名 "encrypteData":data.detail.encryptedData,//用户敏感信息 "iv":data.detail.iv //解密算法的向量 }, success: (result) => { } }) console.log("code:", code); } }) } else { console.log("400", "登录失败"); } } }) }
PAGE里面.....
后端
/** encrypteData,code,iv = 前端传递; OpenId open = getOpenId(code); String sessionKey = open.getSession_key(); // 获取sessionKey public static OpenId getOpenId(String code) throws IOException { String url = "https://api.weixin.qq.com/sns/jscode2session?appid=" + APPID + "&secret=" + SECRET + "&js_code=" + code + "&grant_type=authorization_code"; return JSON.parseObject(IOUtils.toString(HttpUtil.get(url), "UTF-8"), OpenId.class); } */ // 非敏感数据解析.(前端传递是一个JSON字符串,将其解析成为JSON对象) JSONObject rawDataJson = JSON.parseObject(rawData); String avatar = String.valueOf(rawDataJson.get("avatarUrl")); String nickname = String.valueOf(rawDataJson.get("nickName")); int gender = Integer.valueOf(String.valueOf(rawDataJson.get("gender"))); JSONObject userInfo = WxService.getUserInfo(encrypteData, session_key, iv); String phoneNumber = userInfo.getString("phoneNumber"); /** * 微信小程序用户数据解析. * @param encryptedData * @param sessionKey * @param iv * @return * @throws Exception */ public static JSONObject getUserInfo(String encryptedData,String sessionKey,String iv) throws Exception { Decoder decoder = Base64.getDecoder(); // 被加密的数据 byte[] dataByte = decoder.decode(encryptedData); // 加密秘钥 byte[] keyByte = decoder.decode(sessionKey); // 偏移量 byte[] ivByte = decoder.decode(iv); // 如果密钥不足16位,那么就补足. 这个if 中的内容很重要 int base = 16; if (keyByte.length % base != 0) { int groups = keyByte.length / base + (keyByte.length % base != 0 ? 1 : 0); byte[] temp = new byte[groups * base]; Arrays.fill(temp, (byte) 0); System.arraycopy(keyByte, 0, temp, 0, keyByte.length); keyByte = temp; } // 初始化 Security.addProvider(new BouncyCastleProvider()); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding","BC"); SecretKeySpec spec = new SecretKeySpec(keyByte, "AES"); AlgorithmParameters parameters = AlgorithmParameters.getInstance("AES"); parameters.init(new IvParameterSpec(ivByte)); cipher.init( Cipher.DECRYPT_MODE, spec, parameters);// 初始化 byte[] resultByte = cipher.doFinal(dataByte); if (null != resultByte && resultByte.length > 0) { String result = new String(resultByte, "UTF-8"); return JSON.parseObject(result); } return null; }
说明:getUserInfor取到的encryptedData,iv和getPhoneNumber函数取到的值不一样,前者取不到手机号。
JAR包引入
<dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcprov-jdk15on</artifactId> <version>1.56</version> </dependency> // 最后面给一下OpenId的dto: public class OpenId { // openid. private String openid; // unionid. private String unionid; // errmsg. private String errmsg; // errcode. private String errcode; // session_key. private String session_key; public String getOpenid() { return openid; } public void setOpenid(String openid) { this.openid = openid; } public String getUnionid() { return unionid; } public void setUnionid(String unionid) { this.unionid = unionid; } public String getErrmsg() { return errmsg; } public void setErrmsg(String errmsg) { this.errmsg = errmsg; } public String getErrcode() { return errcode; } public void setErrcode(String errcode) { this.errcode = errcode; } public String getSession_key() { return session_key; } public void setSession_key(String session_key) { this.session_key = session_key; } }