springboot 解析微信小程序获取手机号
2023-12-16 23:58:19
引用依赖包
<dependency>
<groupId>bouncycastle</groupId>
<artifactId>bcprov-jdk14</artifactId>
<version>138</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.80</version>
</dependency>
<dependency>
<groupId>io.github.admin4j</groupId>
<artifactId>http</artifactId>
<version>0.4.6</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk15on -->
<!--解密依赖包-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.4.0</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.70</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.80</version>
<scope>compile</scope>
</dependency>
AccountInfo
public class AccountInfo {
public static String grantType="client_credential";
public static String appId=""; //
public static String appSecret=""; //
public static String accessTokenUrl="https://api.weixin.qq.com/cgi-bin/token" ;
public static String getPhoneNumberUrl="https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=";
}
接口
if (code == null || code.length() == 0) {
return null;
}
String wxAppid = AccountInfo.appId;
// 小程序的 app secret (在微信小程序管理后台获取)
String wxSecret = AccountInfo.appSecret;
// 授权(必填)
String grant_type = AccountInfo.grantType;
// 请求参数
String params = "appid=" + wxAppid + "&secret=" + wxSecret + "&grant_type="
+ grant_type;
try {
String sr = HttpRequest.sendGetSSL(AccountInfo.accessTokenUrl, params);
JSONObject json = null;
System.out.println("sr");
System.out.println(sr);
json = JSON.parseObject(sr);
String access_token = (String) json.get("access_token");
String jsonData = "{\"code\":\"" + telCode + "\"}";
Object data = JSON.parse(jsonData);
String sr1 = HttpRequest.sendPostSSl(AccountInfo.getPhoneNumberUrl + access_token, data);
System.out.println("sr1");
System.out.println(sr1);
json = JSON.parseObject(sr1);
Integer errcode = (Integer) json.get("errcode");
if (errcode== 0) {
String tel = (String) JSON.parseObject(json.get("phone_info").toString()).get("phoneNumber");
//去数据库里面查询
if (tel == null || tel.equals("")) {
return null;
}
} else {
}
} catch (Exception e) {
return null;
}
HttpRequest
public class HttpRequest {
public static void main(String[] args) {
//发送 GET 请求
String s=HttpRequest.sendGet("http://v.qq.com/x/cover/kvehb7okfxqstmc.html?vid=e01957zem6o", "");
System.out.println(s);
// //发送 POST 请求
// String sr=HttpRequest.sendPost("http://www.toutiao.com/stream/widget/local_weather/data/?city=%E4%B8%8A%E6%B5%B7", "");
// JSONObject json = JSONObject.fromObject(sr);
// System.out.println(json.get("data"));
}
/**
* 向指定URL发送GET方法的请求
*
* @param url
* 发送请求的URL
* @param param
* 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
* @return URL 所代表远程资源的响应结果
*/
public static String sendGet(String url, String param) {
String result = "";
BufferedReader in = null;
try {
String urlNameString = url + "?" + param;
URL realUrl = new URL(urlNameString);
// 打开和URL之间的连接
URLConnection connection = realUrl.openConnection();
// 设置通用的请求属性
connection.setRequestProperty("accept", "*/*");
connection.setRequestProperty("connection", "Keep-Alive");
connection.setRequestProperty("user-agent",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
// 建立实际的连接
connection.connect();
// 获取所有响应头字段
Map<String, List<String>> map = connection.getHeaderFields();
// 遍历所有的响应头字段
for (String key : map.keySet()) {
System.out.println(key + "--->" + map.get(key));
}
// 定义 BufferedReader输入流来读取URL的响应
in = new BufferedReader(new InputStreamReader(
connection.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
result += line;
}
} catch (Exception e) {
System.out.println("发送GET请求出现异常!" + e);
e.printStackTrace();
}
// 使用finally块来关闭输入流
finally {
try {
if (in != null) {
in.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
System.out.println("result");
System.out.println(result);
return result;
}
/**
* http get请求 请求参数在url后面拼接
* @throws Exception
*/
public static String sendGetSSl(String requestUrl, String param,Map<String,String> header) throws Exception{
HttpsURLConnection conn = null;
InputStream input = null;
BufferedReader br = null;
StringBuffer buffer = null;
try {
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, new TrustManager[] { new TrustAnyTrustManager() },new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
String urlNameString = requestUrl + "?" + param;
URL url = new URL(urlNameString);
conn = (HttpsURLConnection) url.openConnection();
conn.setSSLSocketFactory(sc.getSocketFactory());
conn.setHostnameVerifier(new TrustAnyHostnameVerifier());
conn.setDoOutput(false);
conn.setDoInput(true);
conn.setUseCaches(false);
conn.setConnectTimeout(1000 * 100);
conn.setReadTimeout(1000 * 100);
conn.setRequestMethod("GET");
conn.setRequestProperty("Accept", "*/*");
conn.setRequestProperty("Connection", "keep-alive");
conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
conn.setRequestProperty("Charset", "UTF-8");
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
//添加header
if(header != null){
for(Map.Entry<String, String> entry : header.entrySet()){
String mapKey = entry.getKey();
String mapValue = entry.getValue();
conn.setRequestProperty(mapKey, mapValue);
}
}
conn.connect();
// 读取服务器端返回的内容
System.out.println("======================响应体=========================");
System.out.println("ResponseCode:" + conn.getResponseCode() + ",ResponseMessage:" + conn.getResponseMessage());
if(conn.getResponseCode()==200){
input = conn.getInputStream();
}else{
input = conn.getErrorStream();
}
br = new BufferedReader(new InputStreamReader(input, "UTF-8"));
buffer = new StringBuffer();
String line = null;
while ((line = br.readLine()) != null) {
buffer.append(line);
}
System.out.println("返回报文:" + buffer.toString());
} catch (Exception e) {
System.out.println("发送GET请求出现异常!" + e);
e.printStackTrace();
} finally {
try {
if (conn != null) {
conn.disconnect();
conn = null;
}
if (br != null) {
br.close();
br = null;
}
} catch (IOException ex) {
throw new Exception(ex);
}
}
return buffer.toString();
}
public static String sendGetSSL(String requestUrl,String param){
String urlNameString = requestUrl + "?" + param;
Response response = HttpUtil.get(urlNameString);
ResponseBody responseBody = response.body();
okio.BufferedSource source = responseBody.source();
try {
source.request(Long.MAX_VALUE); // Buffer the entire body.
okio.Buffer buffer = source.buffer();
Charset charset = StandardCharsets.UTF_8;
MediaType contentType = responseBody.contentType();
if (contentType != null) {
charset = contentType.charset(StandardCharsets.UTF_8);
}
return buffer.clone().readString(charset);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static String sendPostSSl(String requestUrl,Object body){
Response response= HttpUtil.post(requestUrl, body);
ResponseBody responseBody = response.body();
okio.BufferedSource source = responseBody.source();
try {
source.request(Long.MAX_VALUE); // Buffer the entire body.
okio.Buffer buffer = source.buffer();
Charset charset = StandardCharsets.UTF_8;
MediaType contentType = responseBody.contentType();
if (contentType != null) {
charset = contentType.charset(StandardCharsets.UTF_8);
}
return buffer.clone().readString(charset);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
* 向指定 URL 发送POST方法的请求
*
* @param url
* 发送请求的 URL
* @param param
* 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
* @return 所代表远程资源的响应结果
*/
public static String sendPost(String url, String param) {
PrintWriter out = null;
BufferedReader in = null;
String result = "";
try {
URL realUrl = new URL(url);
// 打开和URL之间的连接
URLConnection conn = realUrl.openConnection();
// 设置通用的请求属性
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
// 发送POST请求必须设置如下两行
conn.setDoOutput(true);
conn.setDoInput(true);
// 获取URLConnection对象对应的输出流
out = new PrintWriter(conn.getOutputStream());
// 发送请求参数
out.print(param);
// flush输出流的缓冲
out.flush();
// 定义BufferedReader输入流来读取URL的响应
in = new BufferedReader(
new InputStreamReader(conn.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
result += line;
}
} catch (Exception e) {
System.out.println("发送 POST 请求出现异常!"+e);
e.printStackTrace();
}
//使用finally块来关闭输出流、输入流
finally{
try{
if(out!=null){
out.close();
}
if(in!=null){
in.close();
}
}
catch(IOException ex){
ex.printStackTrace();
}
}
return result;
}
}
TrustAnyHostnameVerifier
public class TrustAnyHostnameVerifier implements HostnameVerifier {
public boolean verify(String hname, SSLSession session) {
return true;
}
}
TrustAnyTrustManager
public class TrustAnyTrustManager implements X509TrustManager {
public void checkClientTrusted(java.security.cert.X509Certificate[] var1, String var2) throws java.security.cert.CertificateException{
}
public void checkServerTrusted(java.security.cert.X509Certificate[] var1, String var2) throws java.security.cert.CertificateException{
}
public java.security.cert.X509Certificate[] getAcceptedIssuers(){
return null;
}
}
WeChatUtil
public class WeChatUtil {
/**
* 请求微信接口服务,获取 openid,session_key,unionid,errcode,errmsg
* https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/login/auth.code2Session.html
*
* @param jscode
* @return
*/
public static JSONObject getSessionByCode(String jscode) {
// jscode是前端请求wx.login()方法获取的code;不是getPhoneNumber接口获取的code
// wx.login()方法,需要最先调用,否则可能会报错:pad block corrupted,获取不到解密的信息
String baseUrl = "https://api.weixin.qq.com/sns/jscode2session";
HashMap<String, Object> requestParam = new HashMap<>();
// 小程序 appId
requestParam.put("appid", AccountInfo.appId);
// 小程序 appSecret
requestParam.put("secret", AccountInfo.appSecret);
// 登录时获取的 code(小程序端返回的code)
requestParam.put("js_code", jscode);
// 默认参数,填“authorization_code”
requestParam.put("grant_type", "authorization_code");
// 发送post请求读取调用微信接口获取openid用户唯一标识
String result = HttpUtil.get(baseUrl, requestParam);
return JSONUtil.parseObj(result);
}
/**
* 解密:通过加密密钥,iv偏移量来解密 encryptedData
* 根据encryptedData的不同,解密出来的json数据结构不同(数据结构的详情需要看前端调用的是哪个微信的接口,获取用户哪些信息)
*
* @param encryptData
* @param sessionKey
* @param iv
* @return
*/
public static JSONObject getUserInfo(String encryptData, String sessionKey, String iv) {
// 解密:被加密的数据
byte[] dataByte = Base64.decode(encryptData);
// 解密:加密密钥
byte[] keyByte = Base64.decode(sessionKey);
// 解密:偏移量
byte[] ivByte = Base64.decode(iv);
try {
// 如果密钥不足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;
}
// 初始化
Security.addProvider(new BouncyCastleProvider());
KeyGenerator.getInstance("AES").init(128);
// 生成iv
AlgorithmParameters iv1 = AlgorithmParameters.getInstance("AES");
iv1.init(new IvParameterSpec(ivByte));
// 生成解密
SecretKeySpec secretKeySpec = new SecretKeySpec(keyByte, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, iv1);// 设置为解密模式
byte[] decryptByte = cipher.doFinal(dataByte);
if (null != decryptByte && decryptByte.length > 0) {
String result = new String(decryptByte, "UTF-8");
return JSONUtil.parseObj(result);
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
文章来源:https://blog.csdn.net/weixin_46282323/article/details/135038998
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!