微信小程序获取手机号 实战

先吐槽,由于偷懒 某度一下 没发现完整的代码可以用,需要东拼西凑,没有拿来主义的感觉。

获取手机号

获取微信用户绑定的手机号,需先调用wx.login接口。

因为需要用户主动触发才能发起获取手机号接口,所以该功能不由 API 来调用,需用 button 组件的点击来触发。

注意:目前该接口针对非个人开发者,且完成了认证的小程序开放(不包含海外主体)。需谨慎使用,若用户举报较多或被发现在不必要场景下使用,微信有权永久回收该小程序的该接口权限。

以上是官方说的,根据官方说的实现

https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/getPhoneNumber.html

流程:

1.通过wx.login(Object object)获取登录凭证(code)。通过凭证进而换取用户登录态信息,包括用户的唯一标识(openid)及本次登录的会话密钥(session_key)

wx.login({
        success: res => {
          wx.request({
            url: 'http://192.168.1.128:8088/app/wx/jscodeToSession',
            method: "POST",
            header: {
              'content-type': 'application/x-www-form-urlencoded',
              'Accept': 'application/json'
            },
            dataType: 'json',
            data: {
              js_code: res.code,
            },
            success(res) {
              that.globalData.session_key = res.data.data.session_key;
              that.globalData.openid = res.data.data.openid;
            },
            fail(res) {
              console.log('拉取用户openid失败,将无法正常使用开放接口等服务', res)
            }
          });
          // 发送 res.code 到后台换取 openId, sessionKey, unionId
        }
      })
@RequestMapping(value = "/jscodeToSession", produces = "application/json;charset=UTF-8", method = { RequestMethod.GET,RequestMethod.POST })
	@ResponseBody
	public Map<String,Object> jscodeToSession(String js_code) {//js_code 登录(wx.login())时获取的 code
		Map<String,Object> reMap = new HashMap<String,Object>();
		String v_appid = "小程序 appId";
		String v_secret = "小程序 appSecret";
		String readInterFaceFromUrlByUTF8 = ToolUtil.readInterFaceFromUrlByUTF8("https://api.weixin.qq.com/sns/jscode2session?appid="+v_appid+"&secret="+v_secret+"&js_code="+js_code+"&grant_type=authorization_code");
		JSONObject root = JSONObject.parseObject(readInterFaceFromUrlByUTF8);
		JSONObject data = new JSONObject();
		if(root.containsKey("errcode")){
			reMap.put("success", false);
			data.put("errcode", root.getString("errcode"));
			data.put("errmsg", root.getString("errmsg"));
			reMap.put("data", data);
		}else{
			reMap.put("success", true);
			data.put("session_key", root.getString("session_key"));
			data.put("openid", root.getString("openid"));
			reMap.put("data", data);
		}
		return reMap;
	}
public static String readInterFaceFromUrlByUTF8(String UrlStr) {
		return readInterFaceFromUrl(UrlStr, "utf-8");
	}
public static String readInterFaceFromUrl(String UrlStr, String encode) {
		if (UrlStr.equalsIgnoreCase("") || UrlStr == null)
			return "";
		String reVal = "";
		URL url;
		HttpURLConnection httpConnection = null;
		try {
			url = new URL(UrlStr);
			URLConnection URLconnection = url.openConnection();
			httpConnection = (HttpURLConnection) URLconnection;
			// httpConnection.setRequestMethod("POST");
			int responseCode = httpConnection.getResponseCode();
			System.out.println(responseCode);
			if (responseCode == HttpURLConnection.HTTP_OK) {
				InputStream urlStream = httpConnection.getInputStream();
				BufferedReader bufferedReader = new BufferedReader(
						new InputStreamReader(urlStream, encode));
				String sCurrentLine = "";
				String sTotalString = "";
				while ((sCurrentLine = bufferedReader.readLine()) != null) {
					sTotalString += sCurrentLine;
				}
				reVal = sTotalString;
			} else {
				System.err.println("读取接口失败");
			}
		} catch (Exception e) {
			// e.printStackTrace();
			System.err.println("读取接口异常");
			reVal = "";
		} finally {
			httpConnection.disconnect();
		}
		return reVal;

	}

2.通过button组件来发起获取手机号接口,将事件回调获取到微信服务器返回的加密数据, 再结合 session_key 以及 app_id 进行解密获取手机号

// button组建 放在 wxml里面
<button open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber"></button>

//放到对应的js里面
getPhoneNumber(e) {
    if (e.detail.errMsg == "getPhoneNumber:ok") {
      wx.request({
        url: 'http://192.168.1.128:8088/app/wx/getPhoneNumber',
        method: "POST",
        header: {
          'content-type': 'application/x-www-form-urlencoded',
          'Accept': 'application/json'
        },
        dataType: 'json',
        data: {
          iv: e.detail.iv,
          encryptedData: e.detail.encryptedData, 
          session_key: app.globalData.session_key
        },
        success(res) {
          console.log(res);
        },
        fail(res) {
        }
      });
    }
  }
@RequestMapping(value = "/getPhoneNumber", produces = "application/json;charset=UTF-8", method = { RequestMethod.GET,RequestMethod.POST })
	@ResponseBody
	public Map<String,Object> getPhoneNumber(String session_key,String encryptedData,String iv) {
		Map<String,Object> reMap = new HashMap<String,Object>();
		String v_result = analysisPhoneNumber(session_key,encryptedData,iv);
		JSONObject resultObject = JSONObject.parseObject(v_result);
		reMap.put("phoneNumber", resultObject.getString("phoneNumber"));
		reMap.put("purePhoneNumber", resultObject.getString("purePhoneNumber"));
		reMap.put("countryCode", resultObject.getString("countryCode"));//国家代码
		return reMap;
	}
	
	/**
	 * 解密手机号
	 * @author 
	 * @param session_key
	 * @param encryptedData
	 * @param iv
	 * @return
	 */
	private static String analysisPhoneNumber(String session_key,String encryptedData,String iv ){
		byte[] dataByte = Base64.decode(encryptedData);
		byte[] keyByte = Base64.decode(session_key);
		byte[] ivByte = Base64.decode(iv);
		try {
			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/PKCS5Padding");
			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 result;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
    	return  null;
	}

至此完事。

 

 

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值