在开发过程中获取用户手机号是大多数项目中必不可少的需求,通过微信更加容易获取到用户的手机号,那么今天就来讲讲微信小程序是如何获取到用户的手机的。
以下代码使用伪代码进行讲解。
登录凭证校验
由前端通过wx.login接口获得临时登录凭证code,我们拿到code之后通过登录凭证校验获取到session_key,具体代码如下
public static String login(String appid, String secret,String code) throws IOException{ //API请求地址 String url= "https://api.weixin.qq.com/sns/jscode2session?appid=" + appid + "&secret="+ secret +"&js_code="+ code +"&grant_type=authorization_code"; //通过GET方法请求,具体http请求工具此处不再展示 String s = UrlUtil.doGet(url); if( StringUtils.isEmpty(s) ){ throw new IOException("WxLogin code " + s); } return s; }
该API接口主要返回如下参数:
openid---用户唯一标识
session_key--会话密钥
unionid--用户在开放平台的唯一标识符,在满足UnionID下发条件的情况下会返回(具体说明请参考下面的链接)
注:返回的session_key要全局缓存起来,在以后获取手机号的时候使用。此接口有调用频率限制,每个用户每分钟100次。
参考API文档:https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/login/auth.code2Session.html
解密手机号
第二步就是通过前端传入的encryptedData、iv以及上述获取的session_key来解密用户信息。
encryptedData--包括敏感数据在内的完整用户信息的加密数据
iv--加密算法的初始向量
//先导入解密需要的pom包 org.bouncycastle bcprov-jdk15on 1.56import org.bouncycastle.jce.provider.BouncyCastleProvider;import org.bouncycastle.util.Arrays;import org.bouncycastle.util.encoders.Base64;import javax.crypto.Cipher;import javax.crypto.spec.IvParameterSpec;import javax.crypto.spec.SecretKeySpec;import java.security.Key;import java.security.Security;/** * 微信工具类 */public class WechatDecryptDataUtil { private static final String KEY_ALGORITHM = "AES"; private static final String ALGORITHM_STR = "AES/CBC/PKCS7Padding"; private static Key key; private static Cipher cipher; public static String decryptData(String encryptDataB64, String sessionKeyB64, String ivB64) { return new String( decryptOfDiyIV(Base64.decode(encryptDataB64),Base64.decode(sessionKeyB64),Base64.decode(ivB64))); } private static void init(byte[] keyBytes) { // 如果密钥不足16位,那么就补足. 这个if 中的内容很重要 int base = 16; if (keyBytes.length % base != 0) { int groups = keyBytes.length / base + (keyBytes.length % base != 0 ? 1 : 0); byte[] temp = new byte[groups * base]; Arrays.fill(temp, (byte) 0); System.arraycopy(keyBytes, 0, temp, 0, keyBytes.length); keyBytes = temp; } // 初始化 Security.addProvider(new BouncyCastleProvider()); // 转化成JAVA的密钥格式 key = new SecretKeySpec(keyBytes, KEY_ALGORITHM); try { // 初始化cipher cipher = Cipher.getInstance(ALGORITHM_STR, "BC"); } catch (Exception e) { e.printStackTrace(); } } /** * 解密方法 * @param encryptedData 要解密的字符串 * @param keyBytes 解密密钥 * @param ivs 自定义对称解密算法初始向量 iv * @return 解密后的字节数组 */ private static byte[] decryptOfDiyIV(byte[] encryptedData, byte[] keyBytes, byte[] ivs) { byte[] encryptedText = null; init(keyBytes); try { cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(ivs)); encryptedText = cipher.doFinal(encryptedData); } catch (Exception e) { e.printStackTrace(); } return encryptedText; }}
@Data //此注解是Lombok的注解public class WxPhone { private String phoneNumber; //带区号手机号 private String purePhoneNumber;//纯手机号 private String countryCode;//区号}
String s = WechatDecryptDataUtil.decryptData(encryptedData,session_key, iv);WxPhone wxPhone = JsonUtil.fromJson(s, WxPhone.class);
好啦至此手机号就获取到啦,若有不明白的可以后台留言哟。
【精彩推荐】
图片优雅的转换成Base64
Linux脚本启动jar包
HMAC-MD5签名算法
Java-微信JSSDK