SpringSecurity + jwt + vue2 实现权限管理 , 前端Cookie.set() 设置jwt token无效问题(已解决)

news2024/11/16 6:45:03

问题描述

今天也是日常写程序的一天 , 还是那个熟悉的IDEA , 还是那个熟悉的Chrome浏览器 , 还是那个熟悉的网站 , 当我准备登录系统进行登录的时候 , 发现会直接重定向到登录页 , 后端也没有报错 , 前端也没有报错 , 于是我得脸上又多了一张痛苦面具 , 紧接着在前端疯狂debug…寻找问题 , 我前端登录的部分逻辑是这样的 :

1.登录成功之后 , 后端会响应一个jwt token , 这个jwt token的载荷有角色、权限、用户等信息
2.然后我会判断响应状态码 , 如果是200的话 , 就使用 Cookies.set(TokenKey, token , {expires : val}) 将jwt token存到cookie中 ,如果不是200的话 ,弹出错误消息提示
3.登录成功之后 ,会有一个js文件判断是否可以从cookie获取道token ,如果可以获取到 ,正常路由 , 然后跳转页面 , 如果获取不到的话 , 然后进行重定向到登录页面

这就导致我非常的奇怪 ,后端接口也没有问题 ,jwt token也响应到前端了,并且前端debug的时候也可以拿到 ,但就是**Cookies.set(TokenKey, token , {expires : val})**代码执行完毕之后 ,我f12看了一下cookie ,尽然没有存进去? 瞬间懵逼 , 因为昨天还是好好的 ,唯一就动了菜单表的数据 ,然后我又恢复了一下菜单表 , 发现又可以了 , 紧接着又是一系列的数据比对操作 …以为是数据的问题
在这里插入图片描述

然后还没有找到问题 , 于是我就换了一下思路 , 对比了一下可以登录和不可以登录的两个jwt token , 发现长度不一样 ,于是手动在浏览器添加了一下jwt token,发现报错,这个时候问题也就出来了,由于jwt token中的载荷包含了角色、权限、用户等信息,角色和用户的数据都很小 ,只剩下权限了,而我的权限是再菜单表中的,昨天又只动了菜单表的数据 :

所以问题就是 , jwt生成token的长度是和载荷有关系的,由于昨天加了菜单表的数据 ,导致了jwt载荷比较大 , 从而生成的jwt token 也比较大 ,所以再使用Cookies.set(TokenKey, token , {expires : val}) 将token放入cookie时无效

知道问题之后我的痛苦面具也就没了 ,解决问题就好说了 , 下面是解决办法 :

解决办法

使用压缩算法将jwt的载荷数据进行压缩 ,解析jwt token的时候先将载荷进行解压缩:

代码

	/**
	 * 将数据进行压缩
	 * @param data 数据
	 * @return 压缩之后的结果
	 */
	private String compress(String data) {
		try {
			byte[] input = data.getBytes("UTF-8");
			byte[] output = new byte[input.length];
			Deflater deflater = new Deflater(Deflater.BEST_COMPRESSION);
			deflater.setInput(input);
			deflater.finish();
			int compressedDataLength = deflater.deflate(output);
			byte[] result = new byte[compressedDataLength];
			System.arraycopy(output, 0, result, 0, compressedDataLength);
			return new String(result, "ISO-8859-1");
		} catch (Exception e) {
			throw new RuntimeException("Failed to compress data", e);
		}
	}

	/**
	 * 将压缩之后的数据进行解压
	 * @param compressedData 需要解压的数据
	 * @return 解压之后的数据
	 */
	private String decompress(String compressedData) {
		try {
			byte[] input = compressedData.getBytes("ISO-8859-1");
			byte[] output = new byte[input.length * 2];
			Inflater inflater = new Inflater();
			inflater.setInput(input);
			int decompressedDataLength = inflater.inflate(output);
			byte[] result = new byte[decompressedDataLength];
			System.arraycopy(output, 0, result, 0, decompressedDataLength);
			return new String(result, "UTF-8");
		} catch (Exception e) {
			throw new RuntimeException("Failed to decompress data", e);
		}
	}

使用

这里是创建jwt token的代码 ,解析jwt token的代码也是类似

	/**
	 * 创建JWT
	 *
	 * @param rememberMe  记住我
	 * @param id          用户id
	 * @param subject     用户名
	 * @param roles       用户角色
	 * @param authorities 用户权限
	 * @return {@link String }
	 */
	public String createJWT(Boolean rememberMe, String id, String subject, List<String> roles, Collection<? extends GrantedAuthority> authorities) {
		Date now = new Date();
		Gson gson = new Gson();
		//生成JWT的时间
		long nowMillis = System.currentTimeMillis();
		// 生成加密key
		SecretKey key = generalKey();

		String compress = compress(gson.toJson(authorities));

		// 为payload添加各种标准声明和私有声明了
		JwtBuilder builder = Jwts.builder()
				// 设置jti(JWT ID):是JWT的唯一标识,从而回避重放攻击。
				.setId(id)
				// sub代表这个JWT的主体,即它的所有人。
				.setSubject(subject)
				// jwt签收者
				.setIssuedAt(now)
				// 设置签名使用的签名算法和签名使用的秘钥
				.signWith(SignatureAlgorithm.HS256, key)
				// 创建Payload
				.claim("roles", roles)
				.claim("authorities", compress);

		// 设置过期时间
		long ttlMillis = rememberMe ? Constants.JWT_REMEMBER : Constants.JWT_TTL;
		if (ttlMillis > 0) {
			long expMillis = nowMillis + ttlMillis;
			Date exp = new Date(expMillis);
			builder.setExpiration(exp);
		}

		String jwt = builder.compact();
		// 将生成的JWT保存至Redis
		stringRedisTemplate.opsForValue()
				.set(Constants.REDIS_JWT_KEY_PREFIX + subject, jwt, ttlMillis, TimeUnit.MILLISECONDS);
		return jwt;
	}

到此,问题就解决啦 , 可能编程就是这样 ,编程的过程中会时而遇到困难和挫折,这是相当正常的。同时它是一个充满挑战和解决问题的过程,但也同样带来了许多乐趣和成就感。

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

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

相关文章

WPF中prism模块化

1、参照&#xff08;wpf中prism框架切换页面-CSDN博客&#xff09;文中配置MainView和MainViewModel 2、模块其实就是引用类库&#xff0c;新建两个类库ModuleA ModuleB&#xff0c;修改输出类型为类库,并配置以下文件&#xff1a; ModuleA ModuleAProfile ModuleB Module…

用位运算实现加减乘除法

我们知道计算机只认识0和1&#xff0c;而计算机在计算加减乘除的是也不是我们理解的直接预算&#xff0c;而是通过逻辑运算来实现的&#xff0c;也就是与、非、或、异或&#xff0c;下面就通过这些逻辑运算符来实现加减乘除法 加法&#xff1a;比如11用二进制表示就是00000001…

什么是可持续发展的葡萄酒?

在过去的几年里&#xff0c;消费者越来越意识到他们的日常生活选择对我们的星球和周围环境的潜在影响。我们可以看到使用更少塑料、浪费更少水、食物里程更短的产品越来越受欢迎。这些需求如何转化为葡萄酒世界&#xff1f;这种产品通常要走1000英里才能到达你的杯子。 来自云…

写进简历的软件测试项目实战经验(包含电商、银行、app等)

前言&#xff1a; 今天给大家带来几个软件测试项目的实战总结及经验&#xff0c;适合想自学、转行或者面试的朋友&#xff0c;可以写进简历里的那种哦。 1、项目名称: 家电购 项目描述&#xff1a; “家电购”商城系统是基于 web 浏览器的电子商务系统&#xff0c;通过互联…

3、在docker 容器中安装tomcat

&#xff11;、在服务器上查找tomcat镜像,查看前5条 docker search tomcat --limit 5​​​​​​​ 2、拉取镜像到本地 拉取官方的tomcat到本地 docker pull tomcat:9.0.34-jdk8 3、查看本地镜像 docker images |grep tomcat 4、启动tomcat 服务 使用默认配置 docker ru…

你不知道的测试小技巧——postman接口测试导入导出操作详解

postman中的集合脚本&#xff0c;环境变量、全局变量全部都可以导出&#xff0c;然后分享给团队成员&#xff0c;导出后的脚本可以通过newman生成测试报告。另外还可以将浏览器&#xff0c;抓包工具&#xff0c;接口文档(swagger)中的数据包导入到postman中&#xff0c;并且会自…

知识付费H5页面+后端+全功能制作源码系统

罗峰今天给大家要分享的是知识付费H5页面制作的源码系统&#xff0c;H5也是一种响应式界面&#xff0c;能自动兼容所有的打开设备屏幕&#xff0c;使得页面在不同尺寸的手机、平板等设备上打开时&#xff0c;界面也会自动兼容适应。这也是大部分用户选择H5页面的原因&#xff0…

centos7下 编译coreboot生成真机可用的bios固件, 并在真机上演示 (下篇)

本文章应该是全网最详细的了, 真机版的coreboot bios固件演示了, 希望对你有帮助 centos7下 编译coreboot生成真机可用的bios固件, 并在真机上演示 (上篇)-CSDN博客 文章为上下两大篇 上篇: 文章主要是 一些东西和资料以及步骤 并 编译出可以用于真机的 bios固件 coreboot.r…

漏电断路器

漏电断路器又名漏保。 一、漏电断路器的作用 1、具有空气开关的功能&#xff0c;三相空气开关对任意一相出现过载或短路&#xff0c;均会跳闸。 2、漏电时&#xff0c;L1和L3进线端子之间有220V的电压差&#xff0c;分励脱钩器就可以工作&#xff0c;引起跳闸。 注意&#…

idea 打包 java 项目 报错类似 No valid Maven installation found - 在maven打包前,修改打包名(jar包)

目录 一、idea 打包 java 项目 报错类似 No valid Maven installation found二、在maven打包前&#xff0c;修改打包名参考链接 一、idea 打包 java 项目 报错类似 No valid Maven installation found 解决措施&#xff1a;一定要能看到maven的版本才行&#xff0c;配置到盖层…

剑指offer(C++)-JZ66:构建乘积数组(算法-其他)

作者&#xff1a;翟天保Steven 版权声明&#xff1a;著作权归作者所有&#xff0c;商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处 题目描述&#xff1a; 给定一个数组 A[0,1,...,n-1] ,请构建一个数组 B[0,1,...,n-1] ,其中 B 的元素 B[i]A[0]*A[1]*...*A[i-1]…

C# +.Net C/S架构,在二甲医院全面实际使用三年的LIS系统源码

LIS系统源码技术细节&#xff1a; 体系结构&#xff1a;Client/Server架构 SaaS模式 客户端&#xff1a;WPFWindows Forms 服务端&#xff1a;C# .Net 数据库&#xff1a;Oracle 接口技术&#xff1a;RESTful API HttpWCF LIS检验系统一种专门用于医院化验室的计算机…

发稿渠道和发布新闻的步骤和技巧,收藏!

在现代社会中&#xff0c;新闻的发布和传播起着至关重要的作用。通过新闻&#xff0c;人们可以获取及时的信息&#xff0c;了解社会动态和事件发展。而对于企业和组织来说&#xff0c;通过新闻发布可以宣传品牌、推广产品&#xff0c;增加曝光度&#xff0c;吸引目标受众的关注…

【个人博客公网访问】使用Cpolar+Emlog在Ubuntu上轻松搭建个人博客公网访问

文章目录 前言1. 网站搭建1.1 Emolog网页下载和安装1.2 网页测试1.3 cpolar的安装和注册 2. 本地网页发布2.1 Cpolar临时数据隧道2.2.Cpolar稳定隧道&#xff08;云端设置&#xff09;2.3.Cpolar稳定隧道&#xff08;本地设置&#xff09; 3. 公网访问测试总结 前言 博客作为使…

空开和浪涌保护器的关系及其行业应用解决方案

空开和浪涌保护器是两种常见的电气保护设备&#xff0c;它们各自有不同的工作原理、保护作用和保护范围&#xff0c;但在实际应用中&#xff0c;它们往往需要配合使用&#xff0c;以实现对电气设备和线路的全面保护。本文将介绍空开和浪涌保护器的基本概念、区别和联系&#xf…

JDK安装详细教程

JDK安装详细教程 国内大多数使用的是1.8的版本&#xff0c;对于初学者来说这个版本很友善&#xff0c;不过由于我安装过了1.8&#xff0c;所以我这里演示JDK21 的安装&#xff0c;过程并无区别&#xff0c;只在下载时注意选择1.8版本。1.8就是JDK8. 文章目录 JDK安装详细教程一…

面试了一个30岁的程序员,一个细节就看出来是培训班的····

首先&#xff0c;我说一句&#xff1a;培训出来的&#xff0c;优秀学员大有人在&#xff0c;我不希望因为带着培训的标签而无法达到用人单位和候选人的双向匹配&#xff0c;是非常遗憾的事情。 最近&#xff0c;在网上看到这样一个留言&#xff0c;引发了程序员这个圈子不少的…

内存存储 | 整形在内存中怎么存储呢 | 原码反码补码 | 大小端

整型在内存中的存储 整型在二进制中的表示形式有3种&#xff1a;原码、反码、补码。 正的整数&#xff1a;原码、反码、补码相同负的整数&#xff1a;原码、反码、补码要进行计算的 整数在内存中存储的是补码的二进制序列。 其中对于有符号整形来说&#xff0c;二进制中最高位是…

waf绕过——打狗棒法

前言 某狗可谓是比较好绕过的waf&#xff0c;但是随着现在的发展&#xff0c;某狗也是越来越难绕过了&#xff0c;但是也不是毫无办法&#xff0c;争取这篇文章给正在学习waf绕过的小白来入门一种另类的waf绕过。 环境的搭建&#xff1a; 环境的搭建就选择phpstudy2018安全狗最…

目标和00

题目链接 目标和 题目描述 注意点 只能向数组中的每个整数前添加 ‘’ 或 ‘-’返回可以通过上述方法构造的、运算结果等于 target 的不同 表达式 的数目1 < nums.length < 200 < nums[i] < 10000 < sum(nums[i]) < 10001000 < target < 1000 解答…