栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

springboot整合小程序登录解密获取用户信息

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

springboot整合小程序登录解密获取用户信息

系列文章目录

https://www.cnblogs.com/dw3306/p/13577488.html


文章目录
  • 系列文章目录
  • 一、需要用到的依赖包
  • 二、小程序登录获取用户信息流程
  • 三、参数接受DTO
  • 四、后端发请求的util工具方法
  • 五、登录的接口


一、需要用到的依赖包
        
            org.projectlombok
            lombok
        
        
        
            cn.hutool
            hutool-all
            5.4.0
        
        
        
        
        
            org.bouncycastle
            bcprov-jdk15on
            1.70
        
二、小程序登录获取用户信息流程

  1. 前端请求wx.login()方法获取jscode传给后端;
  2. 后端通过参数jscode、参数appid、参数appsecret请求接口auth.code2Session获取session_key和openid;(用来解密)
  3. 前端请求 wx.getUserInfo()方法获取用户的信息,传给后端;
  4. 后端解密后,存储用户的信息,然后自定义登录状态返回给给前端;
  5. 前端发起业务请求时,携带自定义登录状态。

总的来说:后端只是把前端拿到的加密的用户信息进行解密操作,再自定义登录状态返回给前端。

三、参数接受DTO
@Data
public class WeChatUserInfo {
    // 小程序返回的code
    private String jscode;
    // 不敏感的用户数据(不包括敏感信息的原始数据字符串,用于计算签名)
    private String rawData;
    // 签名(使用 sha1( rawData + sessionkey ) 得到字符串,用于校验用户信息)
    private String signature;
    // 加密数据(包括敏感数据在内的完整用户信息的加密数据)
    private String encryptedData;
    // 加密密钥(加密算法的初始向量)
    private String iv;
}
四、后端发请求的util工具方法
public class WeChatUtil {

    
    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 requestParam = new HashMap<>();
        // 小程序 appId
        requestParam.put("appid", "");
        // 小程序 appSecret
        requestParam.put("secret", "");
        // 登录时获取的 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);
    }

    
    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();
        }
       
五、登录的接口
@RestController
@RequestMapping("/login")
public class WeChatUserLoginController {

    
    @PostMapping
    public String userLogin(@RequestBody WeChatUserInfo weChatUserInfo) {
        // 1.请求微信接口服务,获取openid、sessionKey
        JSONObject session = WeChatUtil.getSessionByCode(weChatUserInfo.getJscode());
        // 2.接收微信接口服务返回的参数:{"session_key":"xxx","openid":"xxx"}
        String openid = session.get("openid", String.class);
        String sessionKey = session.get("session_key", String.class);
        // 3.接收前端传来的用户不敏感信息
        JSONObject rawDataJson = JSONUtil.parseObj(weChatUserInfo.getRawData());
        String nickName = rawDataJson.get("nickName", String.class);
        String avatarUrl = rawDataJson.get("avatarUrl", String.class);
        String gender = rawDataJson.get("gender", String.class);
        String province = rawDataJson.get("province", String.class);
        String city = rawDataJson.get("city", String.class);
        String country = rawDataJson.get("country", String.class);

        // 4.解密获取被加密的数据 encrypteData(比rowData多了appid和openid)
        JSONObject userInfo = WeChatUtil.getUserInfo(weChatUserInfo.getEncryptedData(), sessionKey, weChatUserInfo.getIv());

        // 5.根据需求完成自己的业务(解析json对象获取数据)
        
        // 6.uuid生成唯一key,用于维护微信小程序用户与服务端的会话(或者生成Token)
        String skey = UUID.randomUUID().toString();
        // 7.返回需要的数据给前端
        return "";
    }
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/956117.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号