最近在研究小程序,现在有个需求是获取小程序的手机号码,这个获取接口的权限需要用小程序的企业账号操作可以
首先要进行解密之前获取到sessionKey的值
const APP_ID = 'XXXXXXXXX'; //输入小程序appid
const APP_SECRET = 'xxxxxxxxxxxxxxxxxxxx'; //输入小程序app_secret
var OPEN_ID = '' //储存获取到openid
var SESSION_KEY = '' //储存获取到session_key
Page({
getOpenIdTap: function() {
var that = this;
wx.login({
success: function(data) {
console.log(data);
wx.request({
//获取openid接口
url: 'https://api.weixin.qq.com/sns/jscode2session?appid=' + APP_ID + '&secret=' + APP_SECRET + '&js_code=' + data.code + '&grant_type=authorization_code',
data: {},
method: 'GET',
success: function(res) {
console.log(res.data)
OPEN_ID = res.data.openid; //获取到的openid
SESSION_KEY = res.data.session_key; //获取到session_key
that.setData({
openid: OPEN_ID,
session_key: SESSION_KEY
});
}
})
}
})
}
})
获取到sessionKey以后,还需要在授权登录的时候获取到iv,这步我就省略了
下面是加密方法,这个方法是
public class AESCodeUtils {
// 算法名
public static final String KEY_NAME = "AES";
// 加解密算法/模式/填充方式
// ECB模式只用密钥即可对数据进行加密解密,CBC模式需要添加一个iv
public static final String CIPHER_ALGORITHM = "AES/CBC/PKCS7Padding";
/**
* 微信 数据解密<br/>
* 对称解密使用的算法为 AES-128-CBC,数据采用PKCS#7填充<br/>
* 对称解密的目标密文:encrypted=Base64_Decode(encryptData)<br/>
* 对称解密秘钥:key = Base64_Decode(session_key),aeskey是16字节<br/>
* 对称解密算法初始向量:iv = Base64_Decode(iv),同样是16字节<br/>
*
* @param encrypted 目标密文
* @param session_key 会话ID
* @param iv 加密算法的初始向量
*/
public static String wxDecrypt(String encrypted, String session_key, String iv) {
String json = null;
byte[] encrypted64 = Base64.decodeBase64(encrypted);
byte[] key64 = Base64.decodeBase64(session_key);
byte[] iv64 = Base64.decodeBase64(iv);
byte[] data;
try {
init();
json = new String(decrypt(encrypted64, key64, generateIV(iv64)));
} catch (Exception e) {
e.printStackTrace();
}
return json;
}
/**
* 初始化密钥
*/
public static void init() throws Exception {
Security.addProvider(new BouncyCastleProvider());
KeyGenerator.getInstance(KEY_NAME).init(128);
}
/**
* 生成iv
*/
public static AlgorithmParameters generateIV(byte[] iv) throws Exception {
// iv 为一个 16 字节的数组,这里采用和 iOS 端一样的构造方法,数据全为0
// Arrays.fill(iv, (byte) 0x00);
AlgorithmParameters params = AlgorithmParameters.getInstance(KEY_NAME);
params.init(new IvParameterSpec(iv));
return params;
}
/**
* 生成解密
*/
public static byte[] decrypt(byte[] encryptedData, byte[] keyBytes, AlgorithmParameters iv)
throws Exception {
Key key = new SecretKeySpec(keyBytes, KEY_NAME);
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
// 设置为解密模式
cipher.init(Cipher.DECRYPT_MODE, key, iv);
return cipher.doFinal(encryptedData);
}
}
在这之前需要在pom中添加
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.57</version>
</dependency>
然后
//获取解密的值
String json = AESCodeUtils.wxDecrypt(req.getEncrypteData(), req.getSessionKey(), req.getIv());
json的值为格式为
{"phoneNumber":"13111111111","purePhoneNumber":"13111111111","countryCode":"86","watermark":{"timestamp":1595658760,"appid":"wx3f222f0140ad1d"}}
然后json解析,获取到具体的手机号
//获取手机号
String phoneNo = "";
if (StringUtils.isNotEmpty(json)) {
JSONObject jsonObject = JSONObject.parseObject(json);
if (ObjectUtils.isNotNull(jsonObject)) {
phoneNo = jsonObject.getString("phoneNumber");
}
}
然后后面就按照自己的业务处理问题就可以了