注意:目前该接口针对非个人开发者,且完成了认证的小程序开放(不包含海外主体)。需谨慎使用,若用户举报较多或被发现在不必要场景下使用,微信有权永久回收该小程序的该接口权限。
官网地址如下:
https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/getPhoneNumber.html
1.小程序授权拿到code
wx.login({
success (res) {
if (res.code) {
//发起网络请求
wx.request({
url: 'https://test.com/onLogin',
data: {
code: res.code
}
})
} else {
console.log('登录失败!' + res.errMsg)
}
}
})
2.小程序授权获取手机号标签拿到encryptedData与iv
# 授权按钮,绑定用户点击后的方法 getPhoneNumber()
<button open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber"></button>
js方法:
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;
var code = this.data.wxCode;//小程序授权拿到的code
var _this = this;
api.sendPost({
url: ‘’, //调用后台接口获取用户手机号码
params:{
encrypted: encryptedData,
iv:iv,
code:code
},
success:function(data){
// 获取到的手机号码
var phone = data.phone;
},
fail:function(msg){
})
}
3.后台接口
/*
* 获取小程序用户基本信息
*/
@RequestMapping(value="code2Session", method = RequestMethod.GET)
public ReturnData code2Session(HttpServletRequest req,String code,String encryptedData,String iv) throws Exception {
String code = req.getParameter("code");
//第一步:通过code换取网页授权access_token
String url = "https://api.weixin.qq.com/sns/jscode2session?appid=‘你的小程序appid’&secret=‘你的小程序密钥’&js_code="+code+"&grant_type=authorization_code";
JSONObject jsonObject = WXAuthUtil.doGetJson(url);
Map<String,String> map=new HashMap<>();
map.put("openid",jsonObject.getString("openid"));
map.put("unionid",jsonObject.getString("unionid"));
map.put("session_key",jsonObject.getString("session_key"));
String sessionkey = jsonObject.getString("session_key");
// 解密
byte[] encrypData = Base64Utils.decodeFromString(encryptedData);
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);
map.put("phone",object.getString("phoneNumber"));// 拿到手机号码
return ReturnData.success(map);
}