-
小程序wxml文件中增加授权标签
# 授权按钮,绑定用户点击后的方法 getPhoneNumber()
原生写法 :<button open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber">{{quickLoginTitle}}</button>
uniapp写法 :<button open-type="getPhoneNumber" @getphonenumber="getPhoneNumber">{{quickLoginTitle}}</button>
在小程序js文件中增加getPhoneNumber方法:getPhoneNumber: function (e) { // 参数e是绑定的授权方法自动传入过来的, 主要是为了拿到vi和encryptedData值从后台换取用户联系方式 if ("getPhoneNumber:ok" != e.detail.errMsg){ wx.showToast({ icon:'none', title: '快捷登陆失败' }) return; } var iv = e.detail.iv; var encryptedData = e.detail.encryptedData; // this.data.wxCode, 定义wxCode变量,并在onShow()方法中调用小程序login方法获取code值赋予this.data.wxCode var code = this.data.wxCode; var _this = this; //调用后台接口获取用户手机号码 api.sendPost({ url: api.decode_phone, params:{ encrypted: encryptedData, iv:iv, code:code }, success:function(data){ // 获取到的手机号码 var phone = data.phone; }, fail:function(msg){ }) }
在后台增加接口:@RequestMapping(value = "decode/wxapp/phone", method = RequestMethod.POST) @Override public Result<JSONObject> decodeWxAppPhone( @RequestParam(value = "encrypted") String encrypted, @RequestParam(value = "iv") String iv, @RequestParam(value = "code") String code) { return Result.success(userService.decodeWxAppPhone(encrypted, iv, code)); }
userService.decodeWxAppPhone 内部实现逻辑:// 定义微信解密获取手机号码的接口地址,固定的 String wxAppHost = "https://api.weixin.qq.com"; String wxAppPath = "/sns/jscode2session" String wxAppId = "自己的appid" String wxAppSecret = "自己的wxAppSecret" public JSONObject decodeWxAppPhone(String encrypted, String iv, String code) { String path = wxAppPath + "?appid=" + wxAppId + "&secret=" + wxAppSecret + "&js_code=" + code + "&grant_type=authorization_code"; try { // 向微信服务器发送get请求获取加密了的内容 HttpResponse response = HttpUtils.doGet(wxAppHost, path, "GET", null, null); String jsonStr = EntityUtils.toString(response.getEntity()); JSONObject jsonObject = JSON.parseObject(jsonStr); String sessionkey = jsonObject.getString("session_key"); // 解密 byte[] encrypData = Base64Utils.decodeFromString(encrypted); byte[] ivData = Base64Utils.decodeFromString(iv); byte[] sessionKey = Base64Utils.decodeFromString(sessionkey); AlgorithmParameterSpec ivSpec = new IvParameterSpec(ivData); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); SecretKeySpec keySpec = new SecretKeySpec(sessionKey, "AES"); cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec); String resultString = new String(cipher.doFinal(encrypData), "UTF-8"); JSONObject object = JSONObject.parseObject(resultString); // 拿到手机号码 String phone = object.getString("phoneNumber"); // 返回手机号码 JSONObject returnObject = new JSONObject(); returnObject.put("phone", phone); return returnObject; } catch (Exception e) { log.error("微信小程序手机号码解密异常,信息如下:", e); } }
后台不要打断点,后台不要打断点,后台不要打断点,后台不要打断点,后台不要打断点,切记切记要快速执行过去,否则走不到正确的回调也就拿不到手机号。