开发微信小程序如果要拿到用户信息都需要接入微信登录,这里把和微信对接的地方封装成对应的方法,使用时直接传参调用即可
1.需要导入的jar包
<!--alibaba json工具-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>
2.封装好接收数据实体类
package com.lcp.fitness.dto;
import lombok.Data;
@Data
public class Jscode2Session {
private String openid;
private String session_key;
private String unionid;
}
package com.lcp.fitness.dto;
import lombok.Data;
@Data
public class PhoneNumberDto {
private String phoneNumber;
private String purePhoneNumber;
private String countryCode;
private String watermark;
}
3.封装工具类
package com.lcp.fitness.utils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.lcp.fitness.dto.Jscode2Session;
import com.lcp.fitness.dto.PhoneNumberDto;
import org.springframework.web.client.RestTemplate;
public class WeixinUtil {
private static final String url = "https://api.weixin.qq.com/sns/jscode2session";
public static Jscode2Session getCode(String appId, String appSecret, String code) {
RestTemplate restTemplate = new RestTemplate();
Jscode2Session jscode2Session = null;
String str = restTemplate.getForObject(url + "?appid=" + appId + "&secret=" + appSecret + "&js_code=" + code + "&grant_type=authorization_code", String.class);
jscode2Session = JSONObject.parseObject(str, new TypeReference<Jscode2Session>() {
});
return jscode2Session;
}
public static PhoneNumberDto getPhone(String iv, String encryptedData, String sessionKey) {
String s = null;
try {
s = AES.decryptData(encryptedData, sessionKey, Iv);
} catch (Exception e) {
e.printStackTrace();
}
PhoneNumberDto phoneNumberDto = JSON.parseObject(s, PhoneNumberDto.class);
return phoneNumberDto;
}
}
package com.lcp.fitness.utils;
import 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 AES {
public static void main(String[] args) {
String result = decryptData(
"sDXrUftQyBSyY7M4Ro4Xvjl8amI2agPjUWkcJXTJx6qsqaeetGdE7bp7P7V95aU7TS6O6l9cSznKhw5dhvkjSE+2vH19SntKxvfNtWUJigVKgzB28ACPjROC/4tidR4mMjJO81HX9pMCjusMVdYy0YzlYvvtCgTUNIOHNByMSB5fJ+vXIMnw==",
"9y9P6RqKVZiWg==",
"Yi1SGcsMg=="
);
System.out.println("result = " + result);
}
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 final String KEY_ALGORITHM = "AES";
private static final String ALGORITHM_STR = "AES/CBC/PKCS7Padding";
private static Key key;
private static Cipher cipher;
private static void init(byte[] keyBytes) {
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());
key = new SecretKeySpec(keyBytes, KEY_ALGORITHM);
try {
cipher = Cipher.getInstance(ALGORITHM_STR, "BC");
} catch (Exception e) {
e.printStackTrace();
}
}
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;
}
}
4.测试及说明
微信官方文档地址 先说一下上面用到的几个参数
1.appId:微信小程序id,申请了小程序登录后台即可查看 2.appSecret:秘钥,同样在后台查看,需要小程序管理员权限才可查看,及时保存 3.code:前端通过wx.login(Object object)方法调用,后端只需接收(只能使用一次) 4.sessionKey:使用code从微信服务器获取,后面会使用,后端最好使用redis保存一下 5.iv:加密算法的初始向量,前端调用传给后端 6.encryptedData:包括敏感数据在内的完整用户信息的加密数据,前端调用传给后台
知道了所有参数的来源,就可以测试了
这里我就测试一下通过code获取sessionKey,openId 拿到微信的数据后就可以进行自己的业务操作了
这里说一下解密用户信息的方法,如果解析出来是用户名、头像等而不是手机号,那是因为前端传的加密数据的问题,解析用户信息和手机号都使用同样的方法即可
|