概要
实现微信小程序获取用户手机号,附带前后端代码
整体架构流程
- 微信小程序前端获取code
- 后端消费code请求微信api获取用户unionid、sessionKey
- 前端实现用户点击授权
- 授权之后将解析参数传至后端,后端解析手机号
技术名词解释
- unionid
unionId 是同一用户不同应用的唯一标识 - sessionKey
会话秘钥,用于解析手机号 - appId
微信小程序的应用标识 - appSecret
小程序公众平台用来验证开发者身份的密钥
技术细节
- 前端获取code
onLoad() {
wx.login({
success: (res) => {
this.code = res.code
}
})
},
- 前端获取到code之后,通过接口将code传递至后端,后端通过微信官方提供的api获取用户unionid、sessionKey,获取到信息之后将sessionKey响应至前端
注意:
(1)每一个code只能消费一次且有时效,换取之后,code将会失效
(2)appId 和appSecret 是在微信公众平台注册小程序之后,微信公众平台提供
// 调用微信接口换取 openid 和 session_key
String url = "https://api.weixin.qq.com/sns/jscode2session";
String params = "appid=" + appId + "&secret=" + appSecret + "&js_code=" + loginRequest.getCode()
+ "&grant_type=authorization_code";
String response = OKHttpUtil.httpGet(url + "?" + params);
- 通过微信提供组件调取获取用户手机号授权弹窗,用户授权之后,在点击事件中将微信微信返回的信息传递至后端,由后端解析手机号
注意:
(1)此code和上述code非同一个,不能互相使用,上述code用户换取unionid、sessionKey,此code用于解析手机号
(2)此code同样拥有时效性
<view class="btn-view">
<button class="bottom reject sansSCM" hover-class="none" type="primary">
拒绝
</button>
<button class="bottom sansSCM" hover-class="none" type='primary' open-type="getPhoneNumber"
@getphonenumber="PhoneNumber">
允许
</button>
</view>
//解析手机号
PhoneNumber(e) {
let that = this
if (e.detail.errMsg == "getPhoneNumber:ok") {
getPhoneNum({
"code": e.detail.code,
"encryptedData": e.detail.encryptedData,
"iv": e.detail.iv,
"sessionKey": that.sessionKey,
"unionid": that.unionid,
"avatarUrl": that.avatar,
"nickName": that.nick_name
}).then(res => {
// console.log("手机号信息;", res)
})
} else {
console.log("用户点击了拒绝")
}
}
- 后端接收到信息,对信息进行解密,获取用户手机号
// 解析手机号
private static String decryptData(String encryptedData, String sessionKey, String iv) throws Exception {
byte[] encryptedDataBytes = Base64.getDecoder().decode(encryptedData);
byte[] sessionKeyBytes = Base64.getDecoder().decode(sessionKey);
byte[] ivBytes = Base64.getDecoder().decode(iv);
SecretKeySpec secretKeySpec = new SecretKeySpec(sessionKeyBytes, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
IvParameterSpec ivParameterSpec = new IvParameterSpec(ivBytes);
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
byte[] decryptedDataBytes = cipher.doFinal(encryptedDataBytes);
return new String(decryptedDataBytes, "UTF-8");
}
小结
上述就是微信小程序获取用户手机号授权的全部过程。需要注意的是获取unionid和sessionKey的请求和解析手机号的过程尽量在服务端进行,以保证数据的安全性。