微信小程序登录

微信小程序登录,获取用户手机号

基础类

1
2
3
4
5
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.57</version>
</dependency>
1
2
3
4
5
6
7
8
9
10
@Data
@AllArgsConstructor
@NoArgsConstructor
public class WeiXinLoginVo {
private String openId;
private String session_key;
private String unionid;
private Integer errcode;
private String errmsg;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
/**
* 向指定 URL 发送GET方法的请求
*
* @param url 发送请求的 URL
* @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
* @return 所代表远程资源的响应结果
*/
public static String sendGet(String url, String param) {
StringBuilder result = new StringBuilder();
BufferedReader in = null;
try {
String urlNameString = url;
if (param != null) {
urlNameString = url + "?" + param;
}
URL realUrl = new URL(urlNameString);
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();
in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
result.append(line);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (in != null) {
in.close();
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
return result.toString();
}

获取前端传入的code调用接口获取session_key

1
2
3
4
5
6
7
8
9
10
11
12
// 小程序 appId
@Value("${weixin.appid}")
private String appid;
// 小程序 appSecret
@Value("${weixin.secret}")
private String secret;

public WeiXinLoginVo goLogin(String code) {
String url = "https://api.weixin.qq.com/sns/jscode2session?appid=" + appid + "&secret=" + secret + "&js_code=" + jsCode + "&grant_type=authorization_code";
String result = HttpUtils.sendGet(url, null);
return JSON.parseObject(result, WeiXinLoginVo.class);
}

解密前端传入的encryptedData和iv

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
// 传入sessionKey和其他两个数据
weiXinCommon.decryptOfDiyIV(userLoginVo.getEncryptedData(), sessionKey, userLoginVo.getIv());

private static final String KEY_ALGORITHM = "AES";
private static final String ALGORITHM_STR = "AES/CBC/PKCS7Padding";
private static Key key;
private static Cipher cipher;
/**
* 解密方法
*
* @param encryptedData 要解密的字符串
* @param sessionKeyB64 解密密钥
* @param ivs 自定义对称解密算法初始向量 iv
* @return 解密后的字节数组
*/
public byte[] decryptOfDiyIV(String encryptedData, String sessionKeyB64, String ivs) {
byte[] encryptedDataByte = Base64.decode(encryptedData);
byte[] sessionKeyB64Byte = Base64.decode(sessionKeyB64);
byte[] ivsByte = Base64.decode(ivs);
byte[] encryptedText = null;
init(sessionKeyB64Byte);
try {
cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(ivsByte));
encryptedText = cipher.doFinal(encryptedDataByte);
} catch (Exception e) {
e.printStackTrace();
}
return encryptedText;
}

private 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();
}
}

解密后的数据

1
{phoneNumber=手机号, watermark={"appid":"xxx","timestamp":1592388528}, purePhoneNumber=手机号, countryCode=86}

相关文章

数据库连接池

SpringIOC

Junit和Spring

Tomcat

Servlet

Request,Response和ServletContext

Cookie和Session

JSP和EL和Jstl

Filter和Listener

Mybatis