当前位置: 首页 > news >正文

redis 缓存jwt令牌设置更新时间 BUG修复

大家好,今天我又又又来了,hhhhh。

上文中 我们永redis缓存了token 但是我们发现了 一个bug ,redis中缓存的token  是单用户才能实现的。

就是 我 redis中存储的键 名 为token   值 是jwt令牌 ,但是如果 用户a 登录 之后 创建一个 键 为token的 键值对,如果用户b登录,创建的的键名也是 token ,这样用户b的 jwt 会覆盖 用户a的,就会导致 用户a 的token 会失效呀,这真是一个大大的bug , 按照我目前的水平,我想到了一下 的解决方案 ,既然 token 的键会覆盖,那么我们给 token的键 加上一个唯一标识不就好了  

解决前的代码

package com.example.getway.globalfilter;import cn.hutool.core.collection.CollUtil;
import com.example.getway.Untils.JwtUntils;
import com.example.getway.commen.MessageConstant;
import com.example.getway.pojo.JwtProperties;
import io.jsonwebtoken.Claims;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.server.RequestPath;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.TimeUnit;
@RequiredArgsConstructor
@Slf4j
@Component
public class TokenGlobalFilter implements GlobalFilter, Ordered {private  final JwtProperties jwtProperties;private  final   RedisTemplate redisTemplate;// 这个过滤器 请求的转发@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {//我们只要是非登录请求全都要检验jwt 然后进行 用户信息的传递//获取request对象ServerHttpRequest request = exchange.getRequest();RequestPath requestPath = request.getPath();if(requestPath.toString().contains("/userLogin")){return  chain.filter(exchange);}//获取请求头的 token
//        String redisToken =null;
//        List<String> authorization = request.getHeaders().get("authorization");
//        if (!CollUtil.isEmpty(authorization)) {
//            redisToken = authorization.get(0);
//        }String redisToken = (String)redisTemplate.opsForValue().get(MessageConstant.TOKEN);log.info("token:{}",redisToken);if (redisToken != null ) {//进行jwt的解析try {Claims claims = JwtUntils.parseJwt(redisToken, jwtProperties.getSecretkey());//每次 访问其他资源的时候 都把token更新redisTemplate.expire(MessageConstant.TOKEN, 1000, TimeUnit.DAYS);String loginId = claims.get(MessageConstant.LOGIN_ID).toString();log.info("网关层当前用户的id:{}", Long.valueOf(loginId));//证明 token有效 传递用户信息ServerWebExchange loginId1 = exchange.mutate().request(b -> b.header("loginId", loginId)).build();return chain.filter(loginId1);} catch (Exception e) {log.info("{}",e.getMessage());//出现异常返回一个异常响应ServerHttpResponse response = exchange.getResponse();response.setRawStatusCode(401);return  response.setComplete();}}log.info("token错误");return  exchange.getResponse().setComplete();}
//过滤器链中的优先级 数值越低 优先级就越高@Overridepublic int getOrder() {return 0;}
}

解决前的登陆代码

package com.example.logindemo.cotroller;import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.logindemo.Untils.JwtUntils;
import com.example.logindemo.commen.MessageConstant;
import com.example.logindemo.pojo.JwtProperties;
import com.example.logindemo.pojo.po.UserLogin;
import com.example.logindemo.result.Result;
import com.example.logindemo.service.UserLoginService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.annotations.Param;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.time.Duration;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;@RestController
@Slf4j
@RequiredArgsConstructor
public class LoginController {private  final UserLoginService userLoginService;private final JwtProperties jwtProperties;private  final RedisTemplate redisTemplate;@PostMapping("/userLogin")public Result userLogin( String username,  String password) {password=DigestUtils.md5DigestAsHex(password.getBytes());LambdaQueryWrapper<UserLogin> userLoginLambdaQueryWrapper = new LambdaQueryWrapper<UserLogin>().eq(UserLogin::getUsername, username);UserLogin userLogin = userLoginService.getOne(userLoginLambdaQueryWrapper);if(userLogin==null && userLogin.getUsername().isEmpty()){return Result.error("查询不到用户");}if (username.equals(userLogin.getUsername()) && password.equals(userLogin.getPassword())) {//需要一个map集合  传什么 解析出来什么   一般传的是登录用户的id  我们传1HashMap<String, Object> map = new HashMap<>();map.put(MessageConstant.LOGIN_ID, userLogin.getId());String token = JwtUntils.CreateJwt(map, jwtProperties.getSecretkey());//设置redis缓存为1000天redisTemplate.opsForValue().set(MessageConstant.TOKEN,token,1000,TimeUnit.DAYS);return Result.success(token);}return Result.error("未知错误");}}

解决后 的登录代码  这里只放修改部分

解决后的 网关层过滤代码

现在 我们手动在数据库添加 一个用户  

我们apifox进行登录接口的依次登录 ,然后观察 redis中的缓存数据

 发现token 2 存在  我们也就设置成功了

 

相关文章:

redis 缓存jwt令牌设置更新时间 BUG修复

大家好&#xff0c;今天我又又又来了&#xff0c;hhhhh。 上文中 我们永redis缓存了token 但是我们发现了 一个bug &#xff0c;redis中缓存的token 是单用户才能实现的。 就是 我 redis中存储的键 名 为token 值 是jwt令牌 &#xff0c;但是如果 用户a 登录 之后 创建一个…...

nginx精准禁止特定国家或者地区IP访问

1、安装依赖 dnf -y install gcc-c libtool gd-devel pcre pcre-devel openssl openssl-devel zlib zlib-devel libmaxminddb-devel pcre-devel zlib-devel gcc gcc-c make git2、获取NGINX安装包并安装 wget https://nginx.org/download/nginx-1.26.1.tar.gz git clone http…...

单片机课设-基于单片机的电子时钟设计(仿真+代码+报告)

基于单片机的电子时钟设计 前言一、课设任务是什么?二、系统总体方案硬件设计2.1 系统硬件总体设计2.2 键盘电路设计2.3 DS1302实时时钟芯片电路设计2.4 复位电路2.5 LCD电路设计 三、软件设计3.1 主程序流程图3.2 主要程序设计代码3.3 修改时间函数3.4 扫描键盘函数 四、仿真…...

.net 6 api 修改URL为小写

我们创建的api项目&#xff0c;url是[Route(“[controller]”)]&#xff0c;类似这样子定义的。我们的controller命名是大写字母开头的&#xff0c;显示在url很明显不是很好看&#xff08;url不区分大小写&#xff09;。转换方式&#xff1a; var builder WebApplication.Crea…...

Windows电脑部署Jellyfin服务端并进行远程访问配置详细教程

文章目录 前言1. Jellyfin服务网站搭建1.1 Jellyfin下载和安装1.2 Jellyfin网页测试 2.本地网页发布2.1 cpolar的安装和注册2.2 Cpolar云端设置2.3 Cpolar本地设置 3.公网访问测试4. 结语 前言 本文主要分享如何使用Windows电脑本地部署Jellyfin影音服务并结合cpolar内网穿透工…...

rsync同步目录脚本

假设有两台服务器的示例 IP 地址为&#xff1a; Server A: 192.168.1.100Server B: 192.168.1.200 现在来解释如何使用这个脚本进行服务器之间文件夹内容的同步&#xff0c;保留路径和服务器信息的抽象化。 1. 脚本文件位置和权限 假设脚本文件位于 /root/script.sh&#x…...

LeetCode 6. Z 字形变换

LeetCode 6. Z 字形变换 将一个给定字符串 s 根据给定的行数 numRows &#xff0c;以从上往下、从左到右进行 Z 字形排列。 比如输入字符串为 “PAYPALISHIRING” 行数为 3 时&#xff0c;排列如下&#xff1a; 之后&#xff0c;你的输出需要从左往右逐行读取&#xff0c;产生…...

RTC实时时钟

一、Unix时间戳 1、Unix 时间戳 &#xff08;1&#xff09;Unix 时间戳&#xff08;Unix Timestamp&#xff09;定义为从UTC/GMT的1970年1月1日0时0分0秒开始所经过的秒数&#xff0c;不考虑闰秒 &#xff08;2&#xff09;时间戳存储在一个秒计数器中&#xff0c;秒计数器为…...

WHAT - React 学习系列(一)

官方文档 If you have a lot of HTML to port to JSX, you can use an online converter. You’ll get two things from useState: the current state (count), and the function that lets you update it (setCount). To “remember” things, components use state.To mak…...

代理模式(静态代理/动态代理)

代理模式&#xff08;Proxy Pattern&#xff09; 一 定义 为其他对象提供一种代理&#xff0c;以控制对这个对象的访问。 代理对象在客户端和目标对象之间起到了中介作用&#xff0c;起到保护或增强目标对象的作用。 属于结构型设计模式。 代理模式分为静态代理和动态代理。…...

Word2Vec基本实践

系列文章目录 提示&#xff1a;这里可以添加系列文章的所有文章的目录&#xff0c;目录需要自己手动添加 例如&#xff1a;第一章 Python 机器学习入门之pandas的使用 提示&#xff1a;写完文章后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目…...

IIS配置網站登錄驗證,禁止匿名登陸

需要維護一個以前的舊系統&#xff0c;這個系統在內網運行&#xff0c;需要抓取電腦的登陸賬號&#xff0c;作為權限管理的一部分因此需要在IIS配置一下...

抖音矩阵系统搭建,AI剪辑短视频,一键管理矩阵账号

目录 前言&#xff1a; 一、抖音矩阵系统有哪些功能&#xff1f; 1.AI智能文案 2.多平台账号授权 3.多种剪辑模式 4. 矩阵一键发布&#xff0c;智能发布 5.抖音爆店码功能 6.私信实时互动 7.去水印及外链 二、抖音矩阵系统可以解决哪些问题&#xff1f; 总结&#xff…...

山东大学软件学院创新项目实训开发日志——收尾篇

山东大学软件学院创新项目实训开发日志——收尾篇 项目名称&#xff1a;ModuFusion Visionary&#xff1a;实现跨模态文本与视觉的相关推荐 -------项目目标&#xff1a; 本项目旨在开发一款跨模态交互式应用&#xff0c;用户可以上传图片或视频&#xff0c;并使用文本、点、…...

vue2.7支持组合式API,但是对应的vue-router3并不支持useRoute、useRouter。

最近在做一个项目&#xff0c;因为目标用户浏览器版本并不确定&#xff0c;可能会有较旧版本&#xff0c;于是采用vue2.7而不是vue3&#xff0c;最近一年多使用vue3开发的项目都碰到了很多chrome 63-73版本&#xff0c;而对应UI 库 element plus又问题很多。 为了不碰到这些问…...

摊位纠纷演变肢体冲突,倒赔了500:残疾夫妇与摊主谁之过?

在一个小商贩密集的街区&#xff0c;一起由摊位纠纷引发的肢体冲突事件在当地社区和网络上引起了热议。涉事双方为一名摊主和一对残疾夫妇&#xff0c;他们的争执源自对一个摊位的使用权。本是口头上的争吵&#xff0c;却由于双方情绪激动&#xff0c;迅速升级为肢体冲突&#…...

深入理解和实现Windows进程间通信(消息队列)

常见的进程间通信方法 常见的进程间通信方法有&#xff1a; 管道&#xff08;Pipe&#xff09;消息队列共享内存信号量套接字 下面&#xff0c;我们将详细介绍消息队列的原理以及具体实现。 什么是消息队列&#xff1f; Windows操作系统使用消息机制来促进应用程序与操作系…...

Web网页前端教程免费:引领您踏入编程的奇幻世界

Web网页前端教程免费&#xff1a;引领您踏入编程的奇幻世界 在当今数字化时代&#xff0c;Web前端技术已成为互联网发展的重要驱动力。想要踏入这一领域&#xff0c;掌握相关技能&#xff0c;却苦于找不到合适的教程&#xff1f;别担心&#xff0c;本文将为您带来一份免费的We…...

北斗短报文终端在应急消防通信场景中的应用

在应对自然灾害和紧急情况时&#xff0c;北斗三号短报文终端以其全球覆盖、实时通信和精准定位的能力&#xff0c;成为应急消防通信的得力助手。它不仅能够在地面通信中断的极端条件下保障信息传递的畅通&#xff0c;还能提供精准的位置信息&#xff0c;为救援行动提供有力支持…...

Java跳动爱心代码

1.计算爱心曲线上的点的公式 计算爱心曲线上的点的公式通常基于参数方程。以下是两种常见的参数方程表示方法&#xff0c;用于绘制爱心曲线&#xff1a; 1.1基于 (x, y) 坐标的参数方程 x a * (2 * cos(θ) - sin(θ))^3 y a * (2 * sin(θ) - cos(θ))^3 其中&#xff…...

Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器

第一章 引言&#xff1a;语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域&#xff0c;文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量&#xff0c;支撑着搜索引擎、推荐系统、…...

图表类系列各种样式PPT模版分享

图标图表系列PPT模版&#xff0c;柱状图PPT模版&#xff0c;线状图PPT模版&#xff0c;折线图PPT模版&#xff0c;饼状图PPT模版&#xff0c;雷达图PPT模版&#xff0c;树状图PPT模版 图表类系列各种样式PPT模版分享&#xff1a;图表系列PPT模板https://pan.quark.cn/s/20d40aa…...

Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)

参考官方文档&#xff1a;https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java&#xff08;供 Kotlin 使用&#xff09; 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...

Device Mapper 机制

Device Mapper 机制详解 Device Mapper&#xff08;简称 DM&#xff09;是 Linux 内核中的一套通用块设备映射框架&#xff0c;为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程&#xff0c;并配以详细的…...

[免费]微信小程序问卷调查系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】

大家好&#xff0c;我是java1234_小锋老师&#xff0c;看到一个不错的微信小程序问卷调查系统(SpringBoot后端Vue管理端)【论文源码SQL脚本】&#xff0c;分享下哈。 项目视频演示 【免费】微信小程序问卷调查系统(SpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项…...

Qemu arm操作系统开发环境

使用qemu虚拟arm硬件比较合适。 步骤如下&#xff1a; 安装qemu apt install qemu-system安装aarch64-none-elf-gcc 需要手动下载&#xff0c;下载地址&#xff1a;https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/arm-gnu-toolchain-13.2.rel1-x…...

Proxmox Mail Gateway安装指南:从零开始配置高效邮件过滤系统

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐&#xff1a;「storms…...

SpringAI实战:ChatModel智能对话全解

一、引言&#xff1a;Spring AI 与 Chat Model 的核心价值 &#x1f680; 在 Java 生态中集成大模型能力&#xff0c;Spring AI 提供了高效的解决方案 &#x1f916;。其中 Chat Model 作为核心交互组件&#xff0c;通过标准化接口简化了与大语言模型&#xff08;LLM&#xff0…...

【把数组变成一棵树】有序数组秒变平衡BST,原来可以这么优雅!

【把数组变成一棵树】有序数组秒变平衡BST,原来可以这么优雅! 🌱 前言:一棵树的浪漫,从数组开始说起 程序员的世界里,数组是最常见的基本结构之一,几乎每种语言、每种算法都少不了它。可你有没有想过,一组看似“线性排列”的有序数组,竟然可以**“长”成一棵平衡的二…...

云原生安全实战:API网关Envoy的鉴权与限流详解

&#x1f525;「炎码工坊」技术弹药已装填&#xff01; 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关 作为微服务架构的统一入口&#xff0c;负责路由转发、安全控制、流量管理等核心功能。 2. Envoy 由Lyft开源的高性能云原生…...