在微信小程序开发中,用户手机号的获取是一个常见的需求。通过用户授权,我们可以获取其绑定的手机号。本文将详细介绍如何使用Java解析微信获取的手机号信息。
前提条件
- 微信小程序开发者账号
- 已获取微信小程序的AppID和AppSecret
- 用户已授权手机号获取
流程概述
- 用户在小程序中授权获取手机号。
- 小程序调用微信提供的接口,获取包含手机号的加密数据。
- 将加密数据传递到服务器端。
- 服务器端使用Java解密数据,获取手机号信息。
具体步骤
1. 小程序端获取加密数据
在小程序前端,用户授权后,可以通过wx.getUserProfile
接口获取用户信息,包括加密的手机号数据。
wx.getUserProfile({
desc: '用于获取用户手机号',
success: (res) => {
// 获取加密数据
const encryptedData = res.encryptedData;
const iv = res.iv;
// 将加密数据发送到服务器
wx.request({
url: 'https://yourserver.com/getPhoneNumber',
method: 'POST',
data: {
encryptedData: encryptedData,
iv: iv,
sessionKey: wx.getStorageSync('session_key') // 从登录接口获取的sessionKey
},
success: (res) => {
console.log('手机号解密成功', res.data);
}
});
},
fail: (err) => {
console.error('获取用户信息失败', err);
}
});
2. 服务器端解密数据
在服务器端使用Java解密获取的加密数据。首先,添加微信小程序解密依赖:
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-miniapp</artifactId>
<version>3.8.0</version>
</dependency>
然后,编写解密逻辑:
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.util.SignUtils;
import com.google.gson.JsonParser;
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
public class WeChatPhoneNumberDecryptor {
public static String decrypt(String encryptedData, String sessionKey, String iv) throws Exception {
byte[] dataByte = Base64.decodeBase64(encryptedData);
byte[] keyByte = Base64.decodeBase64(sessionKey);
byte[] ivByte = Base64.decodeBase64(iv);
// 如果密钥不足16位,那么就补足. 这个if 中的内容很重要
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;
}
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKeySpec spec = new SecretKeySpec(keyByte, "AES");
AlgorithmParameterSpec paramSpec = new IvParameterSpec(ivByte);
cipher.init(Cipher.DECRYPT_MODE, spec, paramSpec);
byte[] resultByte = cipher.doFinal(dataByte);
if (resultByte != null && resultByte.length > 0) {
String result = new String(resultByte, StandardCharsets.UTF_8);
return result;
}
return null;
}
public static void main(String[] args) {
String encryptedData = "用户授权获取的encryptedData";
String sessionKey = "用户登录后的sessionKey";
String iv = "用户授权获取的iv";
try {
String result = decrypt(encryptedData, sessionKey, iv);
JsonParser parser = new JsonParser();
String phoneNumber = parser.parse(result).getAsJsonObject().get("phoneNumber").getAsString();
System.out.println("解密后的手机号:" + phoneNumber);
} catch (Exception e) {
e.printStackTrace();
}
}
}
解释
encryptedData
:小程序端传递的加密数据。sessionKey
:通过微信登录接口获取的会话密钥。iv
:初始向量,用于解密。