ZQN
2024-06-17 b1ff19545212508d3f65741ab889f0b6df82a511
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
package com.project.common.utils.wx;
 
 
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
 
import java.util.HashMap;
import java.util.Map;
 
/**
 * @author zsc
 * @date 2020/7/17
 */
@Slf4j
public class AppletsWeChatUtil {
 
    // 登录凭证校验地址
    public final static String GetPageAccessTokenUrl = "https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=CODE&grant_type=authorization_code";
    // 小程序的appId以及appSecret
    private static final String appId = "wx40ebd17aea073b38";
    private static final String appSecret = "707372770de279e04a2fc26cc852456c";
 
 
    /**
     * 小程序授权获取openID和unionID
     *
     * @return
     */
    public static Map<String, String> oauth2GetUnion(String code) {
        String requestUrl = GetPageAccessTokenUrl.replace("APPID", appId).replace("SECRET", appSecret).replace("CODE", code);
        Map<String, String> result = new HashMap<>();
        try {
            /**
             * HttpUtil工具类会在下方贴出,此处也可换成自己的写法,只要是get请求就可以
             * 此处请求返回的json数据包为:
             * openid    string    用户唯一标识
             * session_key    string    会话密钥
             * unionid    string    用户在开放平台的唯一标识符
             * errcode    number    错误码
             * errmsg    string    错误信息
             */
            String response = HttpUtil.get(requestUrl);
            JSONObject jsonResult = JSONObject.parseObject(response);
            System.out.println(jsonResult.toString());
            String openid = String.valueOf(jsonResult.get("openid"));
            // 若用户没有改小程序同主体公众号,则此处unionID为空
            String unionid = String.valueOf(jsonResult.get("unionid"));
            result.put("openid", openid);
            result.put("unionid",unionid);
        } catch (Exception e) {
            log.info("授权获取unionid出现异常");
            e.printStackTrace();
        }
        return result;
    }
 
    /**
     * 小程序授权
     * @param code WxCode
     * @param encryptedData 加密数据
     * @param iv 偏移量iv
     * @return
     */
    public static Map<String, String> oauth2GetUnionIdAndInfo(String code,String encryptedData,String iv) {
        String requestUrl = GetPageAccessTokenUrl.replace("APPID", appId).replace("SECRET", appSecret).replace("CODE", code);
        Map<String, String> result = new HashMap<>();
        try {
            String response = HttpUtil.get(requestUrl);
            JSONObject jsonObject = JSONObject.parseObject(response);
            String openid = String.valueOf(jsonObject.get("openid"));
            // 获取解密所需的session_key
            String session_key = String.valueOf(jsonObject.get("session_key"));
            // 通过AES解密encryptedData 获取union_id,工具类见下方
            String encryptedResult = AESUtil.decrypt(encryptedData, session_key, iv, "UTF-8");
            /**
             * 此处解密之后数据包格式为:
             * openid     string    用户唯一标识
             * nickName  string 昵称
             * gender    string 性别
             * city      string    城市
             * province  string 省份
             * country   string 国家
             * avatarUrl string    头像
             * unionId   string    用户在开放平台的唯一标识符
             * watermark JSON    数据水印,包括appid,timestamp字段 为了校验数据的有效性
             */
            JSONObject parseObject = JSONObject.parseObject(encryptedResult);
            System.out.println(parseObject.toString());
            // ps:此处一定要注意解密的出来的字段名为驼峰命名的unionId,openId,并非直接授权的unionid
            String unionid = String.valueOf(parseObject.get("unionId"));
            result.put("openid", openid);
            result.put("unionid",unionid);
        } catch (Exception e) {
            log.info("授权获取unionid出现异常");
            e.printStackTrace();
        }
        return result;
    }
 
}