Yshop框架的小程序登录

1配置

根据请求头去判断,走小程序,还是Pc端。

#jwt
jwt:header: Authorization#小程序前缀 请求头mini-program-header: MiAuthorization# 令牌前缀token-start-with: Bearersecret: k09BQnaF# 必须使用最少88位的Base64对该令牌进行编码base64-secret: ZmQ0ZGI5NjQ0MDQwY2I4MjMxY2Y3ZmI3MjdhN2ZmMjNhODViOTg1ZGE0NTBjMGM4NDA5NzYxMjdjOWMwYWRmZTBlZjlhNGY3ZTg4Y2U3YTE1ODVkZDU5Y2Y3OGYwZWE1NzUzNWQ2YjFjZDc0NGMxZWU2MmQ3MjY1NzJmNTE0MzI=# 令牌过期时间 此处单位/毫秒 ,默认4小时,可在此网站生成 https://www.convertworld.com/zh-hans/time/milliseconds.htmltoken-validity-in-seconds: 14400000# 在线用户keyonline-key: online-token# 小程序在线用户mi-online-key: mi-online-token# 验证码code-key: code-key

2.登录

登录时,设置用户信息存储到redis中。

    /**** 根据账户,密码 登录* @param exUser* @return*/@Overridepublic R<Object> VxLogin(ExUser exUser) {// 查询数据库中的账号密码是否存在ExUser exUserA = exUserMapper.selectOne(new LambdaQueryWrapper<ExUser>().eq(StringUtils.isNotBlank(exUser.getUserUsername()), ExUser::getUserUsername, exUser.getUserUsername()).eq(StringUtils.isNotBlank(exUser.getUserPassword()), ExUser::getUserPassword, exUser.getUserPassword()).eq(Objects.nonNull(exUser.getUserStatus()), ExUser::getUserStatus, 1));if (Objects.isNull(exUserA)) {return R.error("该用户未存在");}// 生成tokenString token = tokenUtil.generateTokenA(exUserA);Map<String, Object> authInfo = new HashMap<String, Object>(2) {{put("token", properties.getTokenStartWith() + token);put("user", exUserA);}};RedisUtil.set(properties.getMiOnlineKey() + token, exUserA, properties.getTokenValidityInSeconds() / 1000);return R.success(authInfo);}

3.过滤器

获取请求头,判断是小程序接口还是Pc端接口。

/*** Copyright (C) 2018-2022* All rights reserved, Designed By www.yixiang.co*/
package co.yixiang.modules.security.security;import co.yixiang.domain.ExUser;
import co.yixiang.modules.security.config.SecurityProperties;
import co.yixiang.modules.security.service.OnlineUserService;
import co.yixiang.modules.user.vo.OnlineUser;
import co.yixiang.utils.SpringContextHolder;
import co.yixiang.utils.StringUtils;
import io.jsonwebtoken.ExpiredJwtException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.web.filter.GenericFilterBean;import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;/*** @author /*/
@Slf4j
public class TokenFilter extends GenericFilterBean {@Autowiredprivate SecurityProperties securityProperties;private final TokenUtil tokenUtil;TokenFilter(TokenUtil tokenUtil) {this.tokenUtil = tokenUtil;}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)throws IOException, ServletException {HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;String requestRri = httpServletRequest.getRequestURI();OnlineUser onlineUser = null;ExUser exUser = null;String authToken = null;String authTokenA = null;try {SecurityProperties properties = SpringContextHolder.getBean(SecurityProperties.class);OnlineUserService onlineUserService = SpringContextHolder.getBean(OnlineUserService.class);String clientType = httpServletRequest.getHeader(properties.getHeader());String miniProgramClientType = httpServletRequest.getHeader(properties.getMiniProgramHeader());// 检查是否存在PC端或小程序端的请求头if (clientType == null && miniProgramClientType == null) {log.error("Both Client-Type and Mini-Program-Client-Type headers are missing.");filterChain.doFilter(httpServletRequest, servletResponse);return;}if (StringUtils.isNotBlank(clientType)) {// PC端authToken = tokenUtil.getToken(httpServletRequest);} else if (StringUtils.isNotBlank(miniProgramClientType)) {// 小程序authTokenA = tokenUtil.getTokenA(httpServletRequest);}if (authToken == null && authTokenA == null) {log.error("Both authToken and authTokenA are null.");filterChain.doFilter(httpServletRequest, servletResponse);return;}if (StringUtils.isNotBlank(authToken)) {onlineUser = onlineUserService.getOne(properties.getOnlineKey() + authToken);} else if (StringUtils.isNotBlank(authTokenA)) {exUser = onlineUserService.getOneA(properties.getMiOnlineKey() + authTokenA);
//                String userJson = RedisUtil.get("userA");
//                ExUser user = JSON.parseObject(userJson, ExUser.class);}} catch (ExpiredJwtException e) {log.error(e.getMessage());}// PcString username = StringUtils.isNotBlank(authToken) ? tokenUtil.getUsernameFromToken(authToken) : null;// 小程序String usernameA = StringUtils.isNotBlank(authTokenA) ? tokenUtil.getUsernameFromToken(authTokenA) : null;if (onlineUser != null && username != null && SecurityContextHolder.getContext().getAuthentication() == null && tokenUtil.validateToken(authToken)) {UserDetails userDetails = tokenUtil.getUserDetails(authToken);UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(httpServletRequest));SecurityContextHolder.getContext().setAuthentication(authentication);log.debug("set Authentication to security context for '{}', uri: {}", authentication.getName(), requestRri);}else if(exUser != null && usernameA != null && SecurityContextHolder.getContext().getAuthentication() == null && tokenUtil.validateTokenA(authTokenA)){UserDetails userDetailsA = tokenUtil.getUserDetailsA(authTokenA);UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userDetailsA, null, null);authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(httpServletRequest));SecurityContextHolder.getContext().setAuthentication(authenticationToken);}else {tokenUtil.removeToken(authToken);tokenUtil.removeToken(authTokenA);log.debug("no valid JWT token found, uri: {}", requestRri);}filterChain.doFilter(httpServletRequest, servletResponse);}
}

4. 工具类完善

/*** Copyright (C) 2018-2022* All rights reserved, Designed By www.yixiang.co*/
package co.yixiang.modules.security.security;import co.yixiang.domain.ExUser;
import co.yixiang.modules.security.config.SecurityProperties;
import co.yixiang.modules.security.service.OnlineUserService;
import co.yixiang.modules.user.vo.OnlineUser;
import co.yixiang.utils.SpringContextHolder;
import co.yixiang.utils.StringUtils;
import io.jsonwebtoken.ExpiredJwtException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.web.filter.GenericFilterBean;import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;/*** @author /*/
@Slf4j
public class TokenFilter extends GenericFilterBean {@Autowiredprivate SecurityProperties securityProperties;private final TokenUtil tokenUtil;TokenFilter(TokenUtil tokenUtil) {this.tokenUtil = tokenUtil;}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)throws IOException, ServletException {HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;String requestRri = httpServletRequest.getRequestURI();OnlineUser onlineUser = null;ExUser exUser = null;String authToken = null;String authTokenA = null;try {SecurityProperties properties = SpringContextHolder.getBean(SecurityProperties.class);OnlineUserService onlineUserService = SpringContextHolder.getBean(OnlineUserService.class);String clientType = httpServletRequest.getHeader(properties.getHeader());String miniProgramClientType = httpServletRequest.getHeader(properties.getMiniProgramHeader());// 检查是否存在PC端或小程序端的请求头if (clientType == null && miniProgramClientType == null) {log.error("Both Client-Type and Mini-Program-Client-Type headers are missing.");filterChain.doFilter(httpServletRequest, servletResponse);return;}if (StringUtils.isNotBlank(clientType)) {// PC端authToken = tokenUtil.getToken(httpServletRequest);} else if (StringUtils.isNotBlank(miniProgramClientType)) {// 小程序authTokenA = tokenUtil.getTokenA(httpServletRequest);}if (authToken == null && authTokenA == null) {log.error("Both authToken and authTokenA are null.");filterChain.doFilter(httpServletRequest, servletResponse);return;}if (StringUtils.isNotBlank(authToken)) {onlineUser = onlineUserService.getOne(properties.getOnlineKey() + authToken);} else if (StringUtils.isNotBlank(authTokenA)) {exUser = onlineUserService.getOneA(properties.getMiOnlineKey() + authTokenA);
//                String userJson = RedisUtil.get("userA");
//                ExUser user = JSON.parseObject(userJson, ExUser.class);}} catch (ExpiredJwtException e) {log.error(e.getMessage());}// PcString username = StringUtils.isNotBlank(authToken) ? tokenUtil.getUsernameFromToken(authToken) : null;// 小程序String usernameA = StringUtils.isNotBlank(authTokenA) ? tokenUtil.getUsernameFromToken(authTokenA) : null;if (onlineUser != null && username != null && SecurityContextHolder.getContext().getAuthentication() == null && tokenUtil.validateToken(authToken)) {UserDetails userDetails = tokenUtil.getUserDetails(authToken);UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(httpServletRequest));SecurityContextHolder.getContext().setAuthentication(authentication);log.debug("set Authentication to security context for '{}', uri: {}", authentication.getName(), requestRri);}else if(exUser != null && usernameA != null && SecurityContextHolder.getContext().getAuthentication() == null && tokenUtil.validateTokenA(authTokenA)){UserDetails userDetailsA = tokenUtil.getUserDetailsA(authTokenA);UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userDetailsA, null, null);authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(httpServletRequest));SecurityContextHolder.getContext().setAuthentication(authenticationToken);}else {tokenUtil.removeToken(authToken);tokenUtil.removeToken(authTokenA);log.debug("no valid JWT token found, uri: {}", requestRri);}filterChain.doFilter(httpServletRequest, servletResponse);}
}

5. 获取当前用户数据的工具

判断该接口是否被类实现

/*** Copyright (C) 2018-2022* All rights reserved, Designed By www.yixiang.co*/
package co.yixiang.utils;import cn.hutool.json.JSONObject;
import co.yixiang.domain.ExUser;
import co.yixiang.exception.BadRequestException;
import org.springframework.http.HttpStatus;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;/*** 获取当前登录的用户* @author Zheng Jie* @date 2019-01-17*/
public class SecurityUtils {public static UserDetails getUserDetails() {final Authentication authentication = SecurityContextHolder.getContext().getAuthentication();if (authentication == null) {throw new BadRequestException(HttpStatus.UNAUTHORIZED, "当前登录状态过期");}if(authentication.getPrincipal() instanceof ExUser){return (UserDetails) authentication.getPrincipal();}if (authentication.getPrincipal() instanceof UserDetails) {UserDetails userDetails = (UserDetails) authentication.getPrincipal();UserDetailsService userDetailsService = SpringContextHolder.getBean(UserDetailsService.class);return userDetailsService.loadUserByUsername(userDetails.getUsername());}throw new BadRequestException(HttpStatus.UNAUTHORIZED, "找不到当前登录的信息");}/*** 获取系统用户名称* @return 系统用户名称*/public static String getUsername(){final Authentication authentication = SecurityContextHolder.getContext().getAuthentication();if (authentication == null) {throw new BadRequestException(HttpStatus.UNAUTHORIZED, "当前登录状态过期");}UserDetails userDetails = (UserDetails) authentication.getPrincipal();return userDetails.getUsername();}/*** 获取系统用户id* @return 系统用户id*/public static Long getUserId(){Object obj = getUserDetails();JSONObject json = new JSONObject(obj);return json.get("id", Long.class);}
}

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

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

相关文章

6.13 CO-RE(Compile Once – Run Everywhere)简介

写在前面 BPF CO-RE 即Compile Once – Run Everywhere,编译一次——到处运行。BPF CO-RE是为了解决BPF的可移植性而存在,也就是说编写一个BPF程序,该程序能够成功编译、通过内核验证,并且能够在不同的内核版本上正确运行,而无需为每个特定的内核重新编译。 一,BPF可移…

科技与环保

科技与环保之间存在着密不可分的关系&#xff0c;两者相互影响、相互促进&#xff0c;共同推动着社会的可持续发展。以下是对科技与环保关系的详细分析&#xff1a; 一、科技进步对环保的积极作用 提供技术手段和解决方案&#xff1a;科技进步为环境保护提供了强有力的技术支…

maven项目中报错 could not find class that it depends on找不到所依赖的类

maven工程在程序编译时报错&#xff0c;could not find class that it depends on找不到所依赖的类。 能够引起这种错误的原因&#xff1a;jar包缺失、jar包冲突、jar包不完整、IDE工具问题。 本次解决方案&#xff1a;删除本地仓库中的maven项目&#xff0c;重新install项目&a…

Vue05-数据绑定

一、数据绑定 1-1、v-bind指令 1-2、v-model指令 1、单项数据绑定&#xff1a; 2、双向数据绑定 注意&#xff1a; 表单元素&#xff0c;必须要有属性&#xff1a;value&#xff01;&#xff01;&#xff01; 1-3、小结

【数据库系统概论】触发器

【数据库系统概论】触发器 概述 在数据库系统中&#xff0c;触发器&#xff08;Trigger&#xff09;是一种特殊的存储过程&#xff0c;当特定事件在数据库表上发生时&#xff0c;会自动执行。触发器主要用于确保数据的完整性、一致性和实现复杂的业务规则。触发器是由用户定义…

电拖基础JIAOXUE

1.最简单的TT马达&#xff0c;实际就是一个减速电机&#xff1a; 减速箱的内部包含了一组齿轮。在实际的使用中&#xff0c;绝大部分的电动机都要和减速箱配合使用&#xff0c;因为一般的电机转速都在每分钟几千转甚至1万转以上&#xff0c;而在实际的使用中并不需要这么快的转…

PSO-LSSVM-Adaboost分类模型,粒子群算法优化基于最小二乘支持向量机结合Adaboost的数据分类-附代码

PSO-LSSVM-Adaboost是一种结合PSO-LSSVM和AdaBoost两种机器学习技术的方法&#xff0c;旨在提升模型的性能和鲁棒性。具体来说&#xff0c;AdaBoost是一种集成学习方法&#xff0c;通过组合多个弱分类器来形成一个强分类器&#xff0c;每个分类器针对不同的数据集和特征进行训练…

测试记录3:WLS2运行Linux界面

1.WLS1转到WLS2 &#xff08;1&#xff09;根据自己的平台&#xff0c;下载WLS2安装包 x64: https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi arm64: https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_arm64.msi &#xff08;2&…

Oracle和Random Oracle

Oracle和Random Oracle 在计算机理论里面经常可以看到oracle&#xff0c;这个oracle可以是一个程序 一片代码 一个算法 一个机器 也可以是一个函数 甚至是一个关系。但我们只能知道这个oracle能做什么&#xff0c;不清楚他是怎么做的。所以经常讲其称为黑箱。推广一点&#xf…

音频数据上的会话情感分析

情感分析&#xff0c;也被称为观点挖掘&#xff0c;是自然语言处理(NLP)中一个流行的任务,因为它有着广泛的工业应用。在专门将自然语言处理技术应用于文本数据的背景下,主要目标是训练出一个能够将给定文本分类到不同情感类别的模型。下图给出了情感分类器的高级概述。 例如,三…

2025 QS 世界大学排名公布,北大清华跻身全球前20

一年一度&#xff0c;2025 QS 世界大学排名公布&#xff01; QS&#xff08;Quacquarelli Symonds&#xff09;是唯一一个同时将就业能力与可持续发展纳入评价体系的排名。 继去年 2024 QS 排名因为“墨尔本超耶鲁&#xff0c;新南悉尼高清华”而荣登微博热搜之后&#xff0c…

Jmeter的几种参数化方式

1.为什么要做参数化&#xff1f; 在用jmeter脚本进行压测的时候&#xff0c;为了更真实的模拟起到更好的效果&#xff0c;我们需要让参数动态变化起来&#xff0c;也就是参数化。通过参数化我们也可以更好、更灵活的维护我们的测试脚本。 2.参数化的方式 能够实现参数化的方式有…

兼容SringBoot 3.X版本的 API工具(Springdoc)

前言 逆水行舟&#xff0c;不进则退&#xff01;&#xff01;&#xff01; Springfox 目前最新的还是3.0的版本, 只支持SpringBoot 2.X的版本, SpringDoc 目前最新的版本支持 SpringBoot3.X JDK17 pom依赖 最简单的使用方式就是引入依赖, 然后在控制器上加上对应…

元宇宙的军事应用

目前&#xff0c;“元宇宙”在军事领域的首要用途&#xff0c;是作为模拟训练的“赋能器”。在全球军事领域&#xff0c;美军最早用虚拟仿真开展军事训练。数十年来&#xff0c;美军一直力图打造一个完全模拟现实场景、沉浸式、无缝整合的“虚拟战场系统”。作为新兴技术的集大…

HW面试应急响应之场景题

(1)dns 报警就一定是感染了吗&#xff1f;怎么处理&#xff1f; 不一定。 引起dns报警的情况有&#xff1a;恶意软件感染&#xff0c;域名劫持&#xff0c;DNS欺骗&#xff0c;DDoS攻击等。 处理方法&#xff1a; 1、分析报警&#xff0c;查看报警类型、源IP地址、目标域名等…

使用freebsd-update 升级FreeBSD

为了学习使用AppJail&#xff0c;升级FreeBSD&#xff0c;从14.1-BETA3升级到14.1-RELEASE 当前最新的发布版本是14.1-RELEASE&#xff0c;所以upgrade后面跟了-r 版本号。 使用命令freebsd-update upgrade -r 14.1-RELEASE&#xff1a; freebsd-update upgrade -r 14.1-R…

彻底吃透A*算法的最优性

下面的博客将主要介绍A*算法在扩展结点&#xff08;这对于寻路时间很重要&#xff09;和总代价&#xff08;这对于保证最后解的最优性很重要&#xff09;上的最优性&#xff0c;并将淡化对A *完备性的介绍。 A* 算法流程 A*算法的流程如下[1]&#xff1a; 并定义 f ( n ) f(n…

Pytorch中的广播机制

一、广播(broadcast)机制概述 在PyTorch中&#xff0c;广播机制(Broadcast)允许对不同形状的张量执行逐元素操作&#xff0c;而无需显式地复制数据。这一机制使得编写代码更加简洁和高效。广播机制遵循一定的规则来扩展较小的张量&#xff0c;使其与较大的张量具有相同的形状 …

DNS解析与Bond

一、DNS 1、DNS概念 DNS是域名系统的简称&#xff1a;域名和ip地址之间的映射关系互联网中IP地址是通信的唯一标识&#xff0c;逻辑地址访问网站&#xff0c;有域名&#xff0c;ip地址不好记&#xff0c;域名朗朗上口&#xff0c;好记。 域名解析的目的&#xff1a;实现访问…

LeetCode 算法:最大子数组和c++

原题链接&#x1f517;&#xff1a;最大子数组和 难度&#xff1a;中等⭐️⭐️ 题目 给你一个整数数组 nums &#xff0c;请你找出一个具有最大和的连续子数组&#xff08;子数组最少包含一个元素&#xff09;&#xff0c;返回其最大和。 子数组是数组中的一个连续部分。 …