微信小程序04: 获取openId和unionId

全文目录,一步到位

  • 1.前言简介
    • 1.1 专栏传送门
      • 1.1.1 上文小总结
      • 1.1.2 上文传送门
  • 2. 获取openId和unionId操作
    • 2.1 准备工作
      • 2.1.1 请先复制00篇的统一封装代码
      • 2.1.2 微信登录请求dto
    • 2.2 具体代码使用与注释如下
      • 2.2.1 业务代码
      • 2.2.2 代码解释(一)[无需复制]
      • 2.2.3 获取的map使用方式
        • unionId的解密效果图如下:
      • 2.2.4 解密功能(iv+encryptedData)
    • 2.2.5 微信接口返回值校验
      • 2.2.6 实际使用方式(一行代码)
  • 3. 文章的总结与预告
    • 3.1 本文总结
    • 3.2 下文预告


1.前言简介

1.1 专栏传送门

=> 小程序相关操作专栏 <=

1.1.1 上文小总结

上文主要是大多数微信小程序的整体封装, 代码共用, 而本篇只需要关心业务本身即可, 使用前请先复制上文的代码后使用(请看1.1.2文章传送门)

1.1.2 上文传送门

===> 微信小程序00: 公共封装配置(核心篇)

2. 获取openId和unionId操作

2.1 准备工作

2.1.1 请先复制00篇的统一封装代码

这里强调一下

请先复制核心篇: ===> 微信小程序-00 小程序统一封装类
请先阅读上一篇: ===> 微信小程序01: springboot获取accessToken方式

2.1.2 微信登录请求dto

前三个为参数 后面为业务

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;import javax.validation.constraints.NotBlank;/*** @author pzy* @version 0.1.0* @description: TODO*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
public class WxCommonReqDto {/*** 微信code*/@NotBlank(message = "微信code不能为空")private String wxCode;/*** 微信加密数据*/private String encryptedData;/*** 加密算法的初始向量*/private String iv;/*** 推广标识码")*/private String promotionCode;/*** 手机号*/private String phone;
}

2.2 具体代码使用与注释如下

2.2.1 业务代码

流程解释:
通过wxcode获取的openid作为唯一表示 用于写登录认证逻辑
ps: 一个小程序内的openid是唯一的, 如果是多个小程序并且没有unionId, 数据库存储openid是多对一关系

public AjaxResult wxMiniLogin(WxMiniLoginReqDTO wxMiniLoginReqDTO) {log.info("登录参数:" + JSON.toJSONString(wxMiniLoginReqDTO));String phone = wxMiniLoginReqDTO.getPhone();/*获取微信具体信息*/Map<String, String> wxMiniAuthMap = wechatServiceUtils.getWxMiniAuth(wxMiniLoginReqDTO);//如果前端只传wxCode 没有unionId的需求 只要openId的(直接登录不需要注册)//TODO 业务层代码 返回登录信息token等log.info("===> 当前登录人token信息: {}", JSON.toJSONString(map));return AjaxResult.success("登录成功!", map);}

2.2.2 代码解释(一)[无需复制]

内置两套逻辑 openid和unionId获取信息
用type区分1是unionId 2是openId
decryptResult是字符串类型
1返回的是json字符串 2是纯字符串

public Map<String, String> getWxMiniAuth(WxCommonReqDto wxCommonReqDto) {String code = wxCommonReqDto.getWxCode();//秘钥String encryptedIv = wxCommonReqDto.getIv();//加密数据String encryptedData = wxCommonReqDto.getEncryptedData();JSONObject wxAuthResponse = null;String sessionKey = "";String openid = "";try {//1. 想微信服务器发送请求获取用户信息String url = wechatConfigProperties.getWxLoginUrl(code);log.info("===> 请求微信url是: {}", url);//2. 远程调用微信接口String res = restTemplate.getForObject(url, String.class);wxAuthResponse = JSONObject.parseObject(res);//3. 解析返回参数 报错则进行对应处理/*校验1: wx请求不是null*/if (wxAuthResponse != null) {/*校验2: 响应对象是否正确*/CheckUtils.responseCheck(wxAuthResponse);//3.1 获取session_key和openidsessionKey = wxAuthResponse.getString("session_key");openid = wxAuthResponse.getString("openid");log.info("===> openid:  {}", openid);/*校验3: 响应信息是否正常*/if (StringUtils.isBlank(sessionKey) || StringUtils.isBlank(openid)) {log.error("小程序授权失败,session_key或open_id是空!");throw new ServiceException("抱歉, 小程序授权失败,缺少关键返回参数!");}log.info("===> 微信回调信息: {}", wxAuthResponse);}} catch (Exception e) {e.printStackTrace();throw new ServiceException("抱歉, 小程序授权失败!");}//4. 获取微信信息并制作token/*校验:(选用)如果获取union_id 需要进行解密*/Map<String, String> map = new HashMap<>();String token = "";if (StringUtils.isNotBlank(encryptedIv) && StringUtils.isNotBlank(encryptedData)) {String decryptResult = "";try {//如果没有绑定微信开放平台,解析结果是没有unionid的。decryptResult = AESUtils.decrypt(sessionKey, encryptedIv, encryptedData);if (StringUtils.hasText(decryptResult)) {//如果解析成功,获取tokenmap.put("type", String.valueOf(1));map.put("decryptResult", decryptResult);}} catch (Exception e) {e.printStackTrace();throw new ServiceException("微信登录失败!");}} else {//如果前端只传wxCode 没有unionId的需求 只要openId的map.put("type", String.valueOf(2));map.put("decryptResult", openid);}/*校验: 数据为空的情况*/if (StringUtils.isBlank(map.get("type")) || StringUtils.isBlank(map.get("decryptResult"))) {throw new ServiceException(ResponseEnum.A10007);}return map;}

2.2.3 获取的map使用方式

需要使用unionId的 将注释打开
获取后可以进行后续操作, 比如注册, 登录 等
wx.login()获取的code使用一次即为失效, 切记

        String openId = "";String nickName = "";String unionId = "";String avatarUrl = "";String typeStr = wxMiniAuthMap.get("type");//1 unionId 2 openIdString decryptResult = wxMiniAuthMap.get("decryptResult");if (StringUtils.isBlank(typeStr) || StringUtils.isBlank(decryptResult)) {throw new ServiceException(ResponseEnum.A10007);}int type = Integer.parseInt(typeStr);/*校验: 带解密的 需要union_id的*/if (type == 1) {//字符串转jsonJSONObject jsonObject = JSONObject.parseObject(decryptResult);openId = jsonObject.getString("openId");//openId//TODO 后续支持的功能//      nickName = jsonObject.getString("nickName");//获取nickName//      unionId = jsonObject.getString("unionId");//unionId//      avatarUrl = jsonObject.getString("avatarUrl");//获取头像} else {openId = decryptResult;}
unionId的解密效果图如下:

在这里插入图片描述

2.2.4 解密功能(iv+encryptedData)

AES对称性(CBC)加密 iv偏移量
=> 传送门: AES加密简介与使用

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.jce.provider.BouncyCastleProvider;import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;import javax.validation.constraints.NotNull;
import java.security.Security;
import java.security.spec.AlgorithmParameterSpec;/*** @author pzy* @description TODO* @version 0.1.0*/
@Slf4j
public class AESUtils {// 加密模式private static final String ALGORITHM = "AES/CBC/PKCS7Padding";private static final String CHARSET_NAME = "UTF-8";private static final String AES_NAME = "AES";//解决java.security.NoSuchAlgorithmException: Cannot find any provider supporting AES/CBC/PKCS7Paddingstatic {Security.addProvider(new BouncyCastleProvider());}/*** 解密** @param content 目标密文* @param key     秘钥* @param iv      偏移量* @return*/public static String decrypt(@NotNull String content, @NotNull String key, @NotNull String iv) {try {Cipher cipher = Cipher.getInstance(ALGORITHM);byte[] sessionKey = java.util.Base64.getDecoder().decode(key);SecretKeySpec keySpec = new SecretKeySpec(sessionKey, AES_NAME);byte[] ivByte = java.util.Base64.getDecoder().decode(iv);AlgorithmParameterSpec paramSpec = new IvParameterSpec(ivByte);cipher.init(Cipher.DECRYPT_MODE, keySpec, paramSpec);return new String(cipher.doFinal(Base64.decodeBase64(content)), CHARSET_NAME);} catch (Exception e) {log.error("解密失败:{}", e);e.printStackTrace();}return StringUtils.EMPTY;}public static void main(String[] args) {//接口传入的参数String appid = "";String sessionKey = "";String encryptedData = "";String iv = "";String decrypt = AESUtils.decrypt(encryptedData, sessionKey, iv);System.out.println("解密后:" + decrypt);}

2.2.5 微信接口返回值校验

可以持续维护, 异常码一大堆, 这里仅有40029的响应值校验

    /*** 微信返回值校验** @param wxAuthResponse*/public static void responseCheck(JSONObject wxAuthResponse) {if (wxAuthResponse.containsKey("errcode")) {log.error("===> 异常回调信息: {} ", wxAuthResponse);/*40029 错误的wxCode*/if ("40029".equals(wxAuthResponse.get("errcode"))) {throw new ServiceException("错误的微信code!");}throw new ServiceException("抱歉, 小程序授权失败!");}}

2.2.6 实际使用方式(一行代码)

/*获取微信具体信息*/
Map<String, String> wxMiniAuthMap = wechatServiceUtils.getWxMiniAuth(wxMiniLoginReqDTO);

3. 文章的总结与预告

3.1 本文总结

  • AES加密解密
  • 微信code

3.2 下文预告

  • link码
  • 支付
  • RSA加密


@author: pingzhuyan
@description: ok
@year: 2024

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/27875.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

值传递和址传递

值传递 上面的代码是想要交换x&#xff0c;y的值&#xff0c;把x&#xff0c;y传递给swap函数之后&#xff0c;执行下面的操作&#xff1a; 在swap中a和b交换了&#xff0c;但是和x&#xff0c;y没有关系&#xff0c;所以x&#xff0c;y在main中不会变。 址传递 下面再看把x…

2024FIC决赛

容器密码&#xff1a;2024Fic~Competition~Finals杭州&Powered~By~HL! 案件背景: 2023年3月15日凌晨,受害人短视频平台上看到一段近期火爆的交通事故视频&#xff0c;留言后有人通过私信联系&#xff0c;称有一个赚大钱的机会&#xff0c;该人自称李某&#xff0c;提议让…

软件工程期末复习题

目录 选择 判断 选择 下列说法中正确的是 ( B )。 A、20 世纪50 年代提出了软件工程的概念摇 B、20 世纪60 年代提出了软件工程的概念 C、20 世纪70 年代出现了客户端/ 服务器技术 D、20 世纪80 年代软件工程学科达到成熟 软件危机的主要原因是 ( D )。 A、软件工具落后…

基于STM32移植U8g2图形库——OLED显示(HAL库)

文章目录 一、U8g2简介1、特点2、U8g2的使用步骤 二、I2C相关介绍1、I2C的基本原理2、I2C的时序协议 三、OLED屏的工作原理四、汉字点阵显示原理五、建立STM32CubeMX工程六、U8g2移植1、U8g2源码2、移植过程 七、代码编写1、参考博主实现的U82G的demo例程&#xff08;1&#xf…

【Linux内核】伙伴系统算法和slab分配器(1)

【Linux内核】伙伴系统算法和slab分配器&#xff08;1&#xff09; 目录 【Linux内核】伙伴系统算法和slab分配器&#xff08;1&#xff09;伙伴系统&#xff08;buddy&#xff09;算法伙伴系统算法基本原理内存申请内存回收 接口函数源码分析内存分配接口物理内存释放接口规范…

基于Wireshark实现对FTP的抓包分析

基于Wireshark实现对FTP的抓包分析 前言一、虚拟机Win10环境配置二、FileZilla客户端的安装配置下载FileZilla客户端安装FileZilla 三、FileZilla Server安装下载FileZilla Server安装 四、实现对FTP的抓包前置工作实现抓包完成抓包 前言 推荐一个网站给想要了解或者学习人工智…

Setapp:只需一次订阅,即可获得 240 款+ Mac 软件

为一项任务寻找合适的应用程序是一项相当艰巨的任务。过去&#xff0c;最好的办法要么是花费宝贵的时间搜索可靠的评论&#xff0c;要么就是相信无论安装什么软件都能完成任务。 如果你是 Mac 用户&#xff0c;那么 Setapp 将让这一问题成为过去。无需在需要时下载单个程序&am…

vue之一键部署的shell脚本和它的点.bat文件、海螺AI、ChatGPT

MENU 前言vite.config.ts的配置deploy文件夹的其他内容remote.shpwd.txtdeploy.bat 前言 1、在src同级新建deploy.bat文件&#xff1b; 2、在src同级新建deploy文件夹&#xff0c;文件夹中新建pwd.txt和remote.sh文件&#xff1b; 3、配置好后&#xff0c;直接双击deploy.bat文…

鸿蒙轻内核M核源码分析系列二一 02 文件系统LittleFS

1、LFS文件系统结构体介绍 会分2部分来介绍结构体部分&#xff0c;先介绍LittleFS文件系统的结构体&#xff0c;然后介绍LiteOS-M内核中提供的和LittleFS相关的一些结构体。 1.1 LittleFS的枚举结构体 在openharmony/third_party/littlefs/lfs.h头文件中定义LittleFS的枚举、…

在线时钟python案例

试了一下用通义来编写一些代码&#xff0c;以下是一个在线时钟的样例&#xff0c;只要能运行python就可以使用。 以下是运行后的结果。 代码&#xff08;复制可用&#xff09; import tkinter as tk from time import strftimedef update_time():current_time strftime(&quo…

Postman使用教程(Postman详细图文教程)

本文讲解的是postman工具安装、postman安装教程、postman工具下载、postman使用教程。Postman使得得开发人员和测试人员能够更高效地与Web服务进行交互和调试。 Postman不仅支持常见的HTTP方法&#xff0c;如GET、POST、PUT、DELETE等&#xff0c;还提供了丰富的请求编辑功能&…

20240615给飞凌的OK3588-C开发板刷Rockchip原厂的Buildroot后的测试报告

20240615给飞凌的OK3588-C开发板刷Rockchip原厂的Buildroot后的测试报告&#xff1a; 【切记&#xff0c;由于没有替换DTS的&#xff0c;开发板发热量巨大&#xff01;因此配备鼓风机进行加强散热了】 0、adb 默认没有 1、HDMI IN 4K 2024/6/15 20:32 4K全屏 2、HDMI OUT …

Redis原理篇——分布式锁

Redis原理篇——分布式锁 分布式锁是什么&#xff1f;分布式锁有哪些特性&#xff1f;分布式锁常用实现方式Redis 实现分布式锁一、简单的 Redis 锁二、带过期时间的 Redis 锁三、加上 Owner 的 Redis 锁四、Lua 脚本确保原子性 分布式锁是什么&#xff1f; 分布式锁是在分布式…

软件体系结构笔记(自用)

来自《软件体系结构原理、方法与实践&#xff08;第三版&#xff09;》清华大学出版社 张友生编著 1-8章12章 复习笔记 如有错误&#xff0c;欢迎指正&#xff01;&#xff01;&#xff01;

HCIP认证笔记(填空)

1、为防止攻击者伪造BGP报文对设备进行攻击,可以通过配置GTSM功能检测IP报文中的TTL值的范围来对设备进行保护。如果某台设备配置了“peer x.x.x.x valid-ttl-hops 100",则被检测的报文的TTL值的有效范围为【(156),255】; 解析: peer {group-name | ipv4-address…

学习cel-go了解一下通用表达语言评估是什么

文章目录 1. 前言2. cel-go2.1 cel-go关键概念Applications(应用)Compilation(编译)Expressions(表达式)Environment环境解析表达式的三个阶段 3. cel-go的使用4. cel-go使用5. 说明6. 小结7. 参考 1. 前言 最近因为在项目里面实现的一个使用和||来组合获取字段值的功能有点儿…

MySQL员工练习

MySQL员工练习 1.数据显示 员工信息表emp&#xff1a; 字段&#xff1a;员工id,员工名字,工作岗位,部门经理,受雇日期,薪水,奖金,部门编号 英文名&#xff1a;EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,BONUS,DEPTNO 部门信息表dept&#xff1a; 字段&#xff1a;部门编号,部门名称,部…

自然抽样和平顶抽样

自然抽样和平顶抽样是两种信号处理和采样技术&#xff0c;它们在音频信号处理、信号重建以及数字信号处理中有着不同的应用。 1. 自然抽样&#xff08;也称为理想抽样或无失真抽样&#xff09;&#xff1a;样值脉冲的幅度随原始信号m(t)的幅度而变&#xff1b; 自然抽样过程的…

Java算法常用技巧

一、排序 资料&#xff1a;https://blog.csdn.net/weixin_72499901/article/details/136592073 正排序 import java.util.Arrays;public class SortArray {public static void main(String[] args) {int[] citations {5, 3, 8, 2, 1, 4};// 打印原数组System.out.println(&…

windows10或者windows11怎么查看自己电脑显卡型号

win10系统&#xff1a; 右键单击任务栏后弹出菜单选择任务管理器 打开任务管理器后&#xff0c;点击性能查看左侧GPU0或者GPU1 如果有nvidia字样表示自己电脑有nvidia显卡&#xff0c;如果是AMD或者intel字样表示没有nvidia显卡。注意如果你有GPU0或者GPU1说明你电脑是双显卡&…