java实现小程序授权登录以及获取手机号

news/2024/6/16 9:56:51/文章来源:https://blog.csdn.net/qq_37741426/article/details/137229126

1、引入依赖

       <dependency><groupId>com.github.binarywang</groupId><artifactId>weixin-java-miniapp</artifactId><version>4.1.0</version></dependency>

2、引入封装好的工具类


import cn.binarywang.wx.miniapp.api.WxMaService;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;@Data
public class WxAppInfo {/*** 微信服务*/@JsonIgnoreprivate WxMaService wxMaService;/*** 微信App信息*/private Wxapp wxapp;
}
import cn.binarywang.wx.miniapp.config.impl.WxMaDefaultConfigImpl;
import org.springframework.data.redis.core.RedisTemplate;import java.util.concurrent.TimeUnit;/*** 基于Redis的微信配置provider.*/
@SuppressWarnings("serial")
public class WxMaInRedisConfigStorage extends WxMaDefaultConfigImpl {public static final String ACCESS_TOKEN_KEY = "wx:ma:access_token:";public final static String JSAPI_TICKET_KEY = "wx:ma:jsapi_ticket:";public final static String CARDAPI_TICKET_KEY = "wx:ma:cardapi_ticket:";private final RedisTemplate<String, String> redisTemplate;public WxMaInRedisConfigStorage(RedisTemplate redisTemplate) {this.redisTemplate = redisTemplate;}private String accessTokenKey;private String jsapiTicketKey;private String cardapiTicketKey;/*** 每个公众号生成独有的存储key.*/@Overridepublic void setAppid(String appId) {super.setAppid(appId);this.accessTokenKey = ACCESS_TOKEN_KEY.concat(appId);this.jsapiTicketKey = JSAPI_TICKET_KEY.concat(appId);this.cardapiTicketKey = CARDAPI_TICKET_KEY.concat(appId);}/*** @return*/@Overridepublic String getAccessToken() {return redisTemplate.opsForValue().get(this.accessTokenKey);}/*** @return*/@Overridepublic boolean isAccessTokenExpired() {return redisTemplate.getExpire(accessTokenKey) < 2;}/*** @param accessToken* @param expiresInSeconds*/@Overridepublic synchronized void updateAccessToken(String accessToken, int expiresInSeconds) {redisTemplate.opsForValue().set(this.accessTokenKey, accessToken, expiresInSeconds - 200, TimeUnit.SECONDS);}/****/@Overridepublic void expireAccessToken() {redisTemplate.expire(this.accessTokenKey, 0, TimeUnit.SECONDS);}/*** @return*/@Overridepublic String getJsapiTicket() {return redisTemplate.opsForValue().get(this.jsapiTicketKey);}/*** @return*/@Overridepublic String getCardApiTicket() {return redisTemplate.opsForValue().get(cardapiTicketKey);}
}

3、工具类

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl;
import cn.hutool.core.codec.Base64;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.yami.shop.bean.model.Wxapp;
import com.yami.shop.service.WxAppService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.cert.X509Certificate;
import java.security.spec.AlgorithmParameterSpec;
import java.util.Arrays;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;@Slf4j
@Configuration
public class WxMaConfiguration {private static RedisTemplate redisTemplate;private static WxAppService wxappService;private static Map<String, WxAppInfo> wxAppInfoMap = new ConcurrentHashMap<>();private static Map<String, X509Certificate> wxPlatCertMap = new ConcurrentHashMap<>();public WxMaConfiguration(RedisTemplate redisTemplate, WxAppService wxAppService) {this.redisTemplate = redisTemplate;this.wxappService = wxAppService;}/*** 获取WxMaService** @return*/public static WxAppInfo getWxAppInfo() {//替换你的获取小程序配置信息的sqlWxapp wxapp = wxappService.getOne(Wrappers.<Wxapp>lambdaQuery().orderByDesc(Wxapp::getCreateTime));WxAppInfo wxAppInfo = wxAppInfoMap.get(wxapp.getId());if (wxAppInfo != null && wxAppInfo.getWxMaService() != null) {return wxAppInfo;}WxMaInRedisConfigStorage configStorage = new WxMaInRedisConfigStorage(redisTemplate);configStorage.setAppid(wxapp.getId());configStorage.setSecret(wxapp.getSecret());WxMaService wxMaService = new WxMaServiceImpl();wxMaService.setWxMaConfig(configStorage);wxAppInfo = new WxAppInfo();wxAppInfo.setWxMaService(wxMaService);wxAppInfo.setWxapp(wxapp);wxAppInfoMap.put(wxapp.getId(), wxAppInfo);return wxAppInfo;}/*** @Description:解密手机号*/public static String decrypt(String keyStr, String ivStr, String encDataStr) {try {byte[] encData = Base64.decode(encDataStr.getBytes("GBK"));byte[] iv = Base64.decode(ivStr.getBytes("GBK"));byte[] keyByte = Base64.decode(keyStr.getBytes("GBK"));// 如果密钥不足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;}AlgorithmParameterSpec ivSpec = new IvParameterSpec(iv);Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");SecretKeySpec keySpec = new SecretKeySpec(keyByte, "AES");cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);return new String(cipher.doFinal(encData), "UTF-8");} catch (Exception e) {e.printStackTrace();}return null;}}

4、调用获取小程序openid

   /*** 小程序用户登录** @param loginDTO* @return*/@GetMapping("/login")public void login(String jsCode) {WxMaJscode2SessionResult jscode2session = null;try {jscode2session = WxMaConfiguration.getWxAppInfo().getWxMaService().jsCode2SessionInfo(jsCode);//生成accessToken方法 已经封装好直接调用即可 已做缓存处理
//            String accessToken = WxMaConfiguration.getWxAppInfo()
//                    .getWxMaService().getAccessToken();} catch (Exception e) {e.printStackTrace();}Assert.notNull(jscode2session, "用户信息获取失败,请稍后重试!");User user = userService.getOne(Wrappers.<User>lambdaQuery().eq(User::getOpenId, jscode2session.getOpenid()));if (null == user) {user = new User();//保存用户信息user.setOpenId(jscode2session.getOpenid());}user.setSessionKey(jscode2session.getSessionKey());userService.saveOrUpdate(user);//todo 生成toke登录信息}

5、获取手机号


import jakarta.validation.constraints.NotBlank;
import lombok.Data;
@Data
public class GetPhoneDTO {@NotBlank(message = "encryptedData is required")private String encryptedData;@NotBlank(message = "iv is required")private String iv;@NotBlank(message = "code is required")private String code;private String appId;private Long userId;}/*** 获取用户手机号** @param getPhoneDTO* @return*/
@PostMapping("/getMobile")
public void getMobile(@Valid @RequestBody GetPhoneDTO getPhoneDTO) 
{JSONObject result = JSONObject.parseObject(WxMaConfiguration.decrypt("sessionKey", getPhoneDTO.getIv(), getPhoneDTO.getEncryptedData()));String phone = result.getString("phoneNumber");
}

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

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

相关文章

Redis慢日志

SLOWLOG 是用来读取和重置 Redis 慢查询日志的命令&#xff0c;Redis 2.2.12 版本开始支持 1.Redis 慢查询日志概述 客户端从发送命令到获取返回结果经过了以下几个步骤&#xff1a; 1. 客户端发送命令 2. 该命令进入 Redis 队列排队等待执行 3. Redis 开始执行命令 - Red…

MySQL 数据库基础操作详解

文章目录 MySQL 数据库基础操作详解1. 基本概念2. 库的操作3. 表的操作4. 数据操作5. 示例示例一&#xff1a;创建表和插入数据示例二&#xff1a;查询数据示例三&#xff1a;更新数据示例四&#xff1a;删除数据 MySQL 数据库基础操作详解 MySQL 是一种常用的关系型数据库管理…

设计模式-结构型-享元模式Flyweight

享元模式的特点&#xff1a; 享元模式可以共享相同的对象&#xff0c;避免创建过多的对象实例&#xff0c;从而节省内存资源 使用场景&#xff1a; 常用于需要创建大量相似的对象的情况 享元接口类 public interface Flyweight { void operate(String extrinsicState); } 享…

计算机网络-TCP/IP 网络模型

TCP/IP网络模型各层的详细描述&#xff1a; 应用层&#xff1a;应用层为应用程序提供数据传输的服务&#xff0c;负责各种不同应用之间的协议。主要协议包括&#xff1a; HTTP&#xff1a;超文本传输协议&#xff0c;用于从web服务器传输超文本到本地浏览器的传送协议。FTP&…

计算机视觉之三维重建(5)---双目立体视觉

文章目录 一、平行视图1.1 示意图1.2 平行视图的基础矩阵1.3 平行视图的极几何1.4 平行视图的三角测量 二、图像校正三、对应点问题3.1 相关匹配法3.2 归一化相关匹配法3.3 窗口问题3.4 相关法存在的问题3.5 约束问题 一、平行视图 1.1 示意图 如下图即是一个平行视图。特点&a…

怎样在Linux搭建NTP服务器

搭建 NTP&#xff08;Network Time Protocol&#xff09;服务器可以帮助你在局域网内提供时间同步服务&#xff0c;让网络中的设备都使用统一的时间。以下是在 Linux 系统上搭建 NTP 服务器的基本步骤&#xff1a; 安装 NTP 服务器软件&#xff1a; 在终端中执行以下命令安装 N…

第二十章 红黑树

大家应该都接触过平衡二叉树(AVLTree)&#xff0c;了解到 AVL 树的性质&#xff0c;其实平衡二叉树最大的作用就是查找&#xff0c;AVL 树的查找、插入和删除在平均和最坏情况下都是 O(logn)。AVL 树的效率就是高在这个地方。如果在 AVL 树中插入或删除节点后&#xff0c;使得高…

JUC:synchronized优化——锁的升级过程(偏向锁->轻量级锁->重量级锁)以及内部实现原理

文章目录 锁的类型轻量级锁重量级锁自旋优化偏向锁偏向锁的细节偏向锁的撤销批量重偏向批量撤销锁消除 锁的类型 重量级锁、轻量级锁、偏向锁。 加锁过程&#xff1a;偏向->轻量级->重量级 轻量级锁 轻量级锁的使用场景&#xff1a;如果一个对象虽然有多线程要加锁&am…

HarmonyOS 应用开发之Actor并发模型对比内存共享并发模型

内存共享并发模型指多线程同时执行复数任务&#xff0c;这些线程依赖同一内存并且都有权限访问&#xff0c;线程访问内存前需要抢占并锁定内存的使用权&#xff0c;没有抢占到内存的线程需要等待其他线程释放使用权再执行。 Actor并发模型每一个线程都是一个独立Actor&#xf…

IDEA无法连接虚拟机中的Redis的解决方案,无法连接Jedis,无法ping通虚拟机的解决方案

首先&#xff0c;笔者先说明一下自身的情况&#xff0c;怎么连接都连不上&#xff0c;网上的教程全部都看了一遍&#xff0c;基本上没用得上的&#xff0c;这篇文章里面的解决方案包括了笔者能在网上找到了最全面的办法总结&#xff0c;最后终于是连上了 目录 一.连接Jedis出错…

大数据学习第十一天(复习linux指令3)

1、su和exit su命令就是用于账户切换的系统命令 基本语法&#xff1a;su[-] [用户名] 1&#xff09;-表示是否在切换用户后加载变量&#xff0c;建议带上 2&#xff09;参数&#xff1a;用户名&#xff0c;表示切换用户 3&#xff09;切换用户后&#xff0c;可以通过exit命令退…

数据结构——lesson12排序之归并排序

&#x1f49e;&#x1f49e; 前言 hello hello~ &#xff0c;这里是大耳朵土土垚~&#x1f496;&#x1f496; &#xff0c;欢迎大家点赞&#x1f973;&#x1f973;关注&#x1f4a5;&#x1f4a5;收藏&#x1f339;&#x1f339;&#x1f339; &#x1f4a5;个人主页&#x…

【CANN训练营笔记】AscendCL图片分类应用(C++实现)

样例介绍 基于PyTorch框架的ResNet50模型&#xff0c;对*.jpg图片分类&#xff0c;输出各图片所属分类的编号、名称。 环境介绍 华为云AI1s CPU&#xff1a;Intel Xeon Gold 6278C CPU 2.60GHz 内存&#xff1a;8G NPU&#xff1a;Ascend 310 环境准备 下载驱动 wget ht…

小折叠手机无法使用车上的无线充电?车和手机都没问题

最近看到一个案例——一位新入手Pocket 2的机主&#xff0c;发现自己的手机无法在车上进行无线充电。检查了手机和汽车都没问题&#xff0c;折腾大半天结果发现是电磁线圈没对准无线充电的位置。 无线充电的原理是手机的无线充电电磁线圈对准电磁线圈&#xff0c;通过电磁波感…

Wireshark TS | HTTP 传输文件慢问题

问题背景 之前有几篇文章写过关于应用传输慢的问题&#xff0c;延用之前的老套话&#xff0c;应用传输慢是一种比较常见的问题&#xff0c;慢在哪&#xff0c;为什么慢&#xff0c;有时候光从网络数据包分析方面很难回答的一清二楚&#xff0c;毕竟应用的定义范围实在太广&…

汽车租赁(源码+文档)

汽车租赁&#xff08;小程序、ios、安卓都可部署&#xff09; 文件包含内容程序简要说明含有功能项目截图客户端登录界面首页订单个人信息我的界面新手指引注册界面车型选择支付界面修改信息 管理端用户管理订单管理分类管理 文件包含内容 1、搭建视频 2、流程图 3、开题报告 …

vue3+threejs新手从零开发卡牌游戏(二十四):添加p2战斗逻辑

用代码模拟p2战斗逻辑&#xff0c;按流程进行步骤拆分&#xff1a; 1.p2抽卡 2.p2召唤怪兽上场 3.p2战斗 其中战斗部分分为几种情况&#xff1a; 情况一&#xff1a;p2场上卡牌由大到小进行排序&#xff0c;按序轮询可以攻击的卡牌&#xff0c;然后攻击p1场上卡牌由大到小…

[蓝桥杯嵌入式]hal库 stm32 (DMA串口1收发,采用空闲中断方法)

前言&#xff1a; 本系列教程将 对应外设原理&#xff0c;HAL库与STM32CubeMX结合在一起讲解&#xff0c;使您可以更快速的学会各个模块的使用 所用工具&#xff1a; 1、芯片&#xff1a; STM32G431RBT6 2、STM32CubeMx软件 3、IDE&#xff1a; MDK-Keil软件 4、STM32G4xx…

supersqli-攻防世界

题目 加个报错 1 and 11 #没报错判断为单引号字符注入 爆显位 1 order by 2#回显正常 1 order by 3#报错 说明列数是2 尝试联合查询 -1 union select 1,2# 被过滤了 return preg_match("/select|update|delete|drop|insert|where|\./i",$inject); select|update|d…

SpringBoot+thymeleaf完成视频记忆播放功能

一、背景 1)客户要做一个视频播放功能,要求是系统能够记录观看人员在看视频时能够记录看到了哪个位置,在下次观看视频的时候能够从该位置进行播放。 2)同时,也要能够记录是谁看了视频,看了百分之多少。 说明:由于时间关系和篇幅原因,我们这里只先讨论第一个要求,第…