前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >微信小程序中针对微信基础库新旧不同版本获取用户手机号的方法

微信小程序中针对微信基础库新旧不同版本获取用户手机号的方法

作者头像
跟着飞哥学编程
发布2022-11-30 21:29:24
发布2022-11-30 21:29:24
2.2K00
代码可运行
举报
运行总次数:0
代码可运行

1.下面是微信官方关于获取手机号的文档链接

获取手机号 | 微信开放文档微信开发者平台文档

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

2.微信基础库版本2.21.2以上时,即新版本库无需提前调用wx.login();旧版本必须先调用wx.login();

我的业务场景是为了微信授权一键登录,我这里做个新旧版本的兼容处理。

3.官方的代码示例,不能直接 CV 使用,下面粘上我个人亲测可用的示例代码

3.1先来一个触发按钮

代码语言:javascript
代码运行次数:0
运行
复制
<button type="primary" open-type="getPhoneNumber" @getphonenumber="getPhoneNumber">获取手机号码</button>

3.2如果微信基础库版本是旧版本( 2.21.2 以下)时,需要先调用wx.login()获取session_key 参数,之后调用getPhoneNumber 函数,此函数直接返回加密字符串,需要页面解密即可得到用户手机号。

此处附上解密工具js文件

WXBizDataCrypt.js文件内容如下:

代码语言:javascript
代码运行次数:0
运行
复制
var crypto = require('crypto')

function WXBizDataCrypt(appId, sessionKey) {
  this.appId = appId
  this.sessionKey = sessionKey
}

WXBizDataCrypt.prototype.decryptData = function (encryptedData, iv) {
  // base64 decode
  var sessionKey = new Buffer(this.sessionKey, 'base64')
  encryptedData = new Buffer(encryptedData, 'base64')
  iv = new Buffer(iv, 'base64')

  try {
     // 解密
    var decipher = crypto.createDecipheriv('aes-128-cbc', sessionKey, iv)
    // 设置自动 padding 为 true,删除填充补位
    decipher.setAutoPadding(true)
    var decoded = decipher.update(encryptedData, 'binary', 'utf8')
    decoded += decipher.final('utf8')
    
    decoded = JSON.parse(decoded)

  } catch (err) {
    throw new Error('Illegal Buffer')
  }

  if (decoded.watermark.appid !== this.appId) {
    throw new Error('Illegal Buffer')
  }

  return decoded
}

module.exports = WXBizDataCrypt

使用页面需要引入一下,路劲写成自己的,我的是放到根目录下的common文件夹下:

代码语言:javascript
代码运行次数:0
运行
复制
import WXBizDataCrypt from "@/common/WXBizDataCrypt.js";

3.3按钮绑定的函数 getPhoneNumber

代码语言:javascript
代码运行次数:0
运行
复制
//微信的login方法
wxAuthLogin(){
		  wx.login({
		    success:(res) => {
		      if (res.code) {
		        //发起网络请求
				//此处请求自己的后台服务,并将输入参数 res.code 传给后台以获取输出参数wxopenid和session_key的值
		      } else {
				  console.log("微信登录失败:"+res.errMsg);
		      }
		    },
			fail(res){
				console.log(res.errMsg);
			}
		  });
	  },
//获取手机号
getPhoneNumber (e) {
		  if(e.detail.errMsg == 'getPhoneNumber:fail user deny'){//拒绝获取手机号
			   console.log("授权失败,用户已拒绝!");
			   //拒绝后可以根据自己的实际场景添加业务逻辑
		  }else{//同意获取手机号
              //此处Common.isExist 是我自定义的判断是否为空的函数,您可以修改为自己的判断非空的方法
			  if(Common.isExist(e.detail.code)){//如果存在code值,则当前环境为新版本
				 //此处根据入参 e.detail.code 请求后台接口,即可得到用户的手机号
				  
			  }else{//微信基础库版本为旧版本
                  //解密方法,第一个参数为小程序的appid,第二个为调用wx.login()并请求后台之后返回的session_key
				  var pc = new WXBizDataCrypt("wx69e6361f588acbe5", this.sessionKey);
				  var data = pc.decryptData(e.detail.encryptedData , e.detail.iv);
                  console.log("解密后的手机号:"+data.purePhoneNumber);
			  }
		  }
	  }

4.平台差异说明,真机预览如下,会提示你的小程序名称申请,微信开发者工具中预览效果有所不一样,只要能调用成功即可。

 5.后台服务接口

5.1 wx.login()请求的后台接口,代码示例如下,此处传入前端wx.login()获取到的code

代码语言:javascript
代码运行次数:0
运行
复制
private static final String appid = "wx****************";
private static final String secret = "7b****************e98bb6";

public static ReturnData getOpenIdAndSessionKey(String code) {
		if(StringUtil.isEmpty(code)){
			return new ReturnData(ReturnCode.FAIL.getCode(), "微信小程序获取openid失败,参数code为空!");
		}
		String url = "https://api.weixin.qq.com/sns/jscode2session?appid="+appid+"&secret="+secret+"&grant_type=authorization_code";
		url += "&js_code="+code;
		try {
			CloseableHttpResponse response = HttpClients.createDefault().execute(new HttpGet(url));
			String ret = EntityUtils.toString(response.getEntity());
			JSONObject jsonObject = JSON.parseObject(ret);
			if(StringUtil.isNotEmpty(jsonObject.getString("openid"))){
				return new ReturnData(ReturnCode.SUCCESS.getCode(), ret, ReturnCode.SUCCESS.getMessage());
			}
			if("0".equals(jsonObject.getString("errcode"))){
				return new ReturnData(ReturnCode.SUCCESS.getCode(), ret, ReturnCode.SUCCESS.getMessage());
			}
			logger.error("微信小程序获取openid错误:{}", jsonObject.getString("errmsg"));
			return new ReturnData(ReturnCode.FAIL.getCode(), "微信小程序获取openid错误");
			
		} catch (ClientProtocolException e) {
			logger.error("微信小程序获取openid异常,ClientProtocolException:{}", e);
			return new ReturnData(ReturnCode.FAIL.getCode(), "微信小程序获取openid异常:ClientProtocolException");
		} catch(IOException e){
			logger.error("微信小程序获取openid异常,IOException:{}", e);
			return new ReturnData(ReturnCode.FAIL.getCode(), "微信小程序获取openid异常:IOException");
		} catch(Exception e){
			logger.error("微信小程序获取openid异常,Exception:{}", e);
			return new ReturnData(ReturnCode.FAIL.getCode(), "微信小程序获取openid异常:Exception");
		}
	}
	public static String getValueByKey(String ret,String key) {
		JSONObject jsonObject = JSON.parseObject(ret);
		return jsonObject.getString(key);
	}

5.2新版本获取手机号的后台接口代码示例:

代码语言:javascript
代码运行次数:0
运行
复制
public static ReturnData getAccessToken() {
		String url = "https://api.weixin.qq.com/cgi-bin/token?appid="+appid+"&secret="+secret+"&grant_type=client_credential";
		try {
			CloseableHttpResponse response = HttpClients.createDefault().execute(new HttpGet(url));
			String ret = EntityUtils.toString(response.getEntity());
			JSONObject jsonObject = JSON.parseObject(ret);
			if(StringUtil.isNotEmpty(jsonObject.getString("access_token"))) {
				return new ReturnData(ReturnCode.SUCCESS.getCode(), jsonObject.getString("access_token"), ReturnCode.SUCCESS.getMessage());
			}
			if("0".equals(jsonObject.getString("errcode"))){
				return new ReturnData(ReturnCode.SUCCESS.getCode(), jsonObject.getString("access_token"), ReturnCode.SUCCESS.getMessage());
			}
			logger.error("微信小程序获取access_token错误:{}", jsonObject.getString("errmsg"));
			return new ReturnData(ReturnCode.FAIL.getCode(), "微信小程序获取access_token错误");
		} catch (ClientProtocolException e) {
			logger.error("微信小程序获取access_token异常,ClientProtocolException:{}", e);
			return new ReturnData(ReturnCode.FAIL.getCode(), "微信小程序获取access_token异常:ClientProtocolException");
		} catch(IOException e){
			logger.error("微信小程序获取access_token异常,IOException:{}", e);
			return new ReturnData(ReturnCode.FAIL.getCode(), "微信小程序获取access_token异常:IOException");
		} catch(Exception e){
			logger.error("微信小程序获取access_token异常,Exception:{}", e);
			return new ReturnData(ReturnCode.FAIL.getCode(), "微信小程序获取access_token异常:Exception");
		}
	}
	
	public static ReturnData getPhone(String code) {
		if(StringUtil.isEmpty(code)){
			return new ReturnData(ReturnCode.FAIL.getCode(), "微信小程序获取手机号失败,参数code为空!");
		}
		ReturnData returnData = getAccessToken();
		if(!ReturnCode.SUCCESS.getCode().equals(returnData.getCode())){
			return returnData;
		}
		String access_token = returnData.getResult();
		String url = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token="+access_token;
		try {
			JSONObject param=new JSONObject();
			param.put("code", code);
			String ret = HttpClientUtil.sendHttpPost2(url, param.toJSONString());
			JSONObject jsonObject = JSON.parseObject(ret);
			if("0".equals(jsonObject.getString("errcode"))){
				jsonObject = jsonObject.getJSONObject("phone_info");
				return new ReturnData(ReturnCode.SUCCESS.getCode(), jsonObject.getString("purePhoneNumber"), ReturnCode.SUCCESS.getMessage());
			}
			logger.error("微信小程序获取手机号错误:{}", jsonObject.getString("errmsg"));
			return new ReturnData(ReturnCode.FAIL.getCode(), "微信小程序获取手机号错误");
		} catch (ClientProtocolException e) {
			logger.error("微信小程序获取手机号异常,ClientProtocolException:{}", e);
			return new ReturnData(ReturnCode.FAIL.getCode(), "微信小程序获取手机号异常:ClientProtocolException");
		} catch(IOException e){
			logger.error("微信小程序获取手机号异常,IOException:{}", e);
			return new ReturnData(ReturnCode.FAIL.getCode(), "微信小程序获取手机号异常:IOException");
		} catch(Exception e){
			logger.error("微信小程序获取手机号异常,Exception:{}", e);
			return new ReturnData(ReturnCode.FAIL.getCode(), "微信小程序获取手机号异常:Exception");
		}
	}

上面获取手机号的方法内用到一个HttpClientUtil.sendHttpPost2 方法的代码如下:

代码语言:javascript
代码运行次数:0
运行
复制
	/**
	 * 向指定 URL 发送POST方法的请求(参数不带名称)
	 */
	public static String sendHttpPost2(String url, String param) throws IOException {
		PrintWriter out = null;
		BufferedReader in = null;
		String result = "";
		try {
			URL realUrl = new URL(url);
			// 打开和URL之间的连接
			URLConnection conn = realUrl.openConnection();
			conn.setConnectTimeout(10000);
			conn.setReadTimeout(300000);
			// 设置通用的请求属性
			conn.setRequestProperty("accept", "*/*");
			conn.setRequestProperty("connection", "Keep-Alive");
			conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
			conn.setRequestProperty("Content-Type", "application/json; charset=utf-8");
			// 发送POST请求必须设置如下两行
			conn.setDoOutput(true);
			conn.setDoInput(true);
			// 获取URLConnection对象对应的输出流
			out = new PrintWriter(new OutputStreamWriter(conn.getOutputStream(), "utf-8"));
			// out = new PrintWriter(conn.getOutputStream());
			// 发送请求参数
			out.print(param);
			// flush输出流的缓冲
			out.flush();
			// 定义BufferedReader输入流来读取URL的响应
			in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"));
			String line;
			while ((line = in.readLine()) != null) {
				result += line;
			}
		}
		// 使用finally块来关闭输出流、输入流
		finally {
			try {
				if (out != null) {
					out.close();
				}
				if (in != null) {
					in.close();
				}
			} catch (IOException ex) {
				ex.printStackTrace();
			}
		}
		return result;
	}

6.到此一个完整的微信小程序获取用户手机号的完整实战案例就结束了,如有错误还请各位大佬能指正。欢迎评论区留言咨询或者讨论。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-03-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.下面是微信官方关于获取手机号的文档链接
  • 2.微信基础库版本2.21.2以上时,即新版本库无需提前调用wx.login();旧版本必须先调用wx.login();
  • 3.官方的代码示例,不能直接 CV 使用,下面粘上我个人亲测可用的示例代码
    • 3.1先来一个触发按钮
    • 3.2如果微信基础库版本是旧版本( 2.21.2 以下)时,需要先调用wx.login()获取session_key 参数,之后调用getPhoneNumber 函数,此函数直接返回加密字符串,需要页面解密即可得到用户手机号。
    • 3.3按钮绑定的函数 getPhoneNumber
  • 4.平台差异说明,真机预览如下,会提示你的小程序名称申请,微信开发者工具中预览效果有所不一样,只要能调用成功即可。
  •  5.后台服务接口
    • 5.1 wx.login()请求的后台接口,代码示例如下,此处传入前端wx.login()获取到的code
    • 5.2新版本获取手机号的后台接口代码示例:
  • 6.到此一个完整的微信小程序获取用户手机号的完整实战案例就结束了,如有错误还请各位大佬能指正。欢迎评论区留言咨询或者讨论。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档