话不多说,直接上代码。
session_key是与用户微信客户端之间通信的密钥,获取用户信息时会用到。
调用:getSessionKeyAndOpenId方法传入code值,返回openid与session_key,
这里的:
appid: 应用唯一标识,在微信开放平台提交应用审核通过后获得
secret: 应用密钥,也是在微信开放平台获得
把下面代码复制粘贴就能直接用了。
@Service
public class WeChatLoginServiceImpl {
@Autowired
private WeChatClient weChatClient;
private static final String APP_ID = "wx2bxxxxx4c2a8";
private static final String APP_SECRET = "72b0ab089db22cc3c9a8e2fxxxxxxx35a";
static {
Security.addProvider(new BouncyCastleProvider());
}
//获取微信用户信息
public String getUserPortionMsg(WxUserDetails details) {
String uxUserMsg = decryptData(details.getEncryptedData(), details.getSession_key(), details.getIv(), "UTF-8");
return uxUserMsg;
}
// 用于加密与解密
public static String decryptData(String data, String key, String iv, String encodingFormat) {
try {
byte[] dataByte = Base64.decodeBase64(data);
byte[] keyByte = Base64.decodeBase64(key);
byte[] ivByte = Base64.decodeBase64(iv);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); // 修改这里
SecretKeySpec spec = new SecretKeySpec(keyByte, "AES");
AlgorithmParameters parameters = AlgorithmParameters.getInstance("AES");
parameters.init(new IvParameterSpec(ivByte));
cipher.init(Cipher.DECRYPT_MODE, spec, parameters);
byte[] resultByte = cipher.doFinal(dataByte);
if (resultByte != null && resultByte.length > 0) {
return new String(resultByte, encodingFormat);
}
return null;
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("解密失败:" + e.getMessage(), e);
}
}
// 返回sessionKey和OpenId
public LoginCertificate getSessionKeyAndOpenId(String code) {
String jsonResponse = weChatClient.getOpenId(APP_ID, APP_SECRET, code, "authorization_code");
LoginCertificate loginCertificate;
try {
// 将JSON字符串解析为LoginCertificate对象
loginCertificate = JSON.parseObject(jsonResponse, LoginCertificate.class);
} catch (Exception e) {
return null;
}
return loginCertificate;
}
}
@Data
public class WxUserDetails {
// 错误消息:如果请求成功,通常为 "getPhoneNumber:ok"
private String errMsg;
// 加密数据:包含敏感信息如用户的手机号码,需要使用session_key进行解密
private String encryptedData;
// 加密算法的初始向量:用于解密encryptedData
private String iv;
// 用户的登录凭证(code):在用户登录时获取,用于请求session_key和openid
private String code;
// 用于解密的session_key
private String session_key;
// 用户的openid
private String openid;
}
@Data
public class LoginCertificate {
private String openid;
private String session_key;
}
@FeignClient(name = "weChatClient", url = "https://api.weixin.qq.com")
public interface WeChatClient {
/**
* 获取微信的openid和session_key
* @param appId
* @param secret
* @param code
* @param grantType
* @return
*/
@GetMapping("/sns/jscode2session")
String getOpenId(@RequestParam("appid") String appId,
@RequestParam("secret") String secret,
@RequestParam("js_code") String code,
@RequestParam("grant_type") String grantType);
}