微信小程序获取用户手机号
流程:先拿到手机号获取凭证code和接口调用凭证access_token,再传入code和access_token参数调用获取手机号接口就可以得到微信用户的手机号。
一.触发获取手机号的授权流程
注:getPhoneNumber 返回的 code 与 wx.login 返回的 code 作用是不一样的,不能混用。
1.接口介绍
//点击按钮后会触发获取手机号的授权流程
<button open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber"></button>
2.代码实现
注:原生小程序记得用bindgetphonenumber,下方代码在uni-app中用@getphonenumber,最终会被编译为小程序的 bindgetphonenumber。
//点击按钮后会触发获取手机号的授权流程
<button open-type="getPhoneNumber" @getphonenumber="getPhone">获取手机号</button>
getPhone(e) {
const that = this; // 保存this引用
console.log(e.detail.code); //手机号获取凭证
getPhone(e.detail.code).then(res => {
console.log("获取手机号res", res.data);
}).catch(err => {
console.error("获取手机号失败", err);
});
},
二.调用微信官方获取接口调用凭据
1.接口介绍(点击标题可跳转至官方文档)
url地址(GET):api.weixin.qq.com/cgi-bin/tok…
描述:获取小程序全局唯一后台接口调用凭据,token有效期为7200s。
2.代码实现如下第三部分
三.调用微信官方获取手机号接口
1.接口介绍(点击标题可跳转至官方文档)
url地址:api.weixin.qq.com/wxa/busines…
描述:该接口用于将code换取用户手机号。
请求参数(必填字段):
access_token 接口调用凭证,code 手机号获取凭证
2.代码实现
@ApiOperation("获取手机号")
@RequestMapping(value = "/getPhone", method = RequestMethod.GET)
@ResponseBody
public CommonResult getPhone(@RequestParam String phoneCode) {
String telephone = WechatUtil.getTelephone(phoneCode);
return CommonResult.success(telephone);
}
//WechatUtil类
public class WechatUtil {
// 配置自己的app_id、app_secret
private static final String APP_ID = "xxx";
private static final String APP_SECRET = "xxx";
public static String getTelephone(String phoneCode) {
String accessToken = getAccess_token(); // 获取 access_token
String url = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=" + accessToken;
// 封装请求体
Map<String, String> paramMap = new HashMap<>();
paramMap.put("code", phoneCode);
// 封装请求头
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<Map<String, String>> httpEntity = new HttpEntity<>(paramMap, headers);
try {
// 通过 RestTemplate 发送请求
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> response = restTemplate.postForEntity(url, httpEntity, String.class);
// 检查 HTTP 响应状态码
if (response.getStatusCode() != HttpStatus.OK) {
throw new RuntimeException("微信接口请求失败,HTTP状态码: " + response.getStatusCodeValue());
}
// 解析响应 JSON
JSONObject jsonResponse = JSONUtil.parseObj(response.getBody());
// 检查微信接口返回的错误码
if (jsonResponse.getInt("errcode") != 0) {
throw new RuntimeException("微信接口返回错误: " + jsonResponse.getStr("errmsg"));
}
// 提取 phone_info 中的 phoneNumber
JSONObject phoneInfo = jsonResponse.getJSONObject("phone_info");
if (phoneInfo == null) {
throw new RuntimeException("微信接口返回数据中未找到 phone_info");
}
String phoneNumber = phoneInfo.getStr("phoneNumber");
if (phoneNumber == null || phoneNumber.isEmpty()) {
throw new RuntimeException("手机号为空");
}
return phoneNumber; // 返回纯手机号(如 "1937232xxxx")
} catch (Exception e) {
// 记录错误日志
System.err.println("获取手机号失败: " + e.getMessage());
throw new RuntimeException("获取手机号失败", e);
}
}
public static String getAccess_token() {
String url = "https://api.weixin.qq.com/cgi-bin/token";
String requestUrl = UriComponentsBuilder.fromHttpUrl(url)
.queryParam("appid", APP_ID)
.queryParam("secret", APP_SECRET)
.queryParam("grant_type", "client_credential")
.toUriString();
HttpResponse response = HttpUtil.createGet(requestUrl).execute();
// 获取 session_key 和 openid
JSONObject parseObj = JSONUtil.parseObj(response.body());
String access_token = (String) parseObj.get("access_token");
return access_token;
}
}