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

问题描述

今天也是日常写程序的一天 , 还是那个熟悉的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();// 生成加密keySecretKey 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保存至RedisstringRedisTemplate.opsForValue().set(Constants.REDIS_JWT_KEY_PREFIX + subject, jwt, ttlMillis, TimeUnit.MILLISECONDS);return jwt;}

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

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

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

相关文章

uniapp 使用和引入 thorui

1. npm install thorui-uni 2. "easycom": { "autoscan": true, "custom": { "tui-(.*)": "thorui-uni/lib/thorui/tui-$1/tui-$1.vue" } }, 3.

XML外部实体注入攻击XXE

xml是扩展性标记语言&#xff0c;来标记数据、定义数据类型&#xff0c;是一种允许用户对自己的标记语言进行定义的源语言。XML文档结构包括XML声明、DTD文档类型定义&#xff08;可选&#xff09;、文档元素&#xff0c;一般无法直接打开&#xff0c;可以选择用excl或记事本打…

CentOS 7下JumpServer安装及配置(超详细版)

前言 Jumpserver是一种用于访问和管理远程设备的Web应用程序&#xff0c;通常用于对服务器进行安全访问。它基于SSH协议&#xff0c;提供了一个安全和可管理的环境来管理SSH访问。Jumpserver是基于Python开发的一款开源工具&#xff0c;其提供了强大的访问控制功能&#xff0c;…

NLP项目:维基百科文章爬虫和分类【02】 - 语料库转换管道

一、说明 我的NLP项目在维基百科条目上下载、处理和应用机器学习算法。相关上一篇文章中&#xff0c;展示了项目大纲&#xff0c;并建立了它的基础。首先&#xff0c;一个 Wikipedia 爬网程序对象&#xff0c;它按名称搜索文章&#xff0c;提取标题、类别、内容和相关页面&…

CSS 中几种常用的换行方法

1、使用 br 元素&#xff1a; 最简单的换行方法是在需要换行的位置插入 元素。例如&#xff1a; <p>This is a sentence.<br>It will be on a new line.</p>这会在 “This is a sentence.” 和 “It will be on a new line.” 之间创建一个换行。 效果&a…

云表:MES系统是工业4.0数字化转型的核心

随着信息技术与工业技术的深度融合&#xff0c;网络、计算机技术、信息技术、软件与自动化技术相互交织&#xff0c;产生了全新的价值模式。在制造领域&#xff0c;这种资源、信息、物品和人相互关联的模式被德国人定义为“工业4.0”&#xff0c;也就是第四次工业革命。工业4.0…

C#中的Dispatcher:Invoke与BeginInvoke的使用

Dispatcher是.NET框架中的一个重要概念&#xff0c;用于处理异步消息传递。在C#中&#xff0c;Dispatcher提供了两种方法&#xff1a;Invoke和BeginInvoke&#xff0c;用于控制线程上消息的顺序和执行方式。 目录 一、Dispatcher.Invoke二、Dispatcher.BeginInvoke三、使用场景…

flink1.15 savepoint 超时报错 java.util.concurrent.TimeoutException

savepoint命令 flink savepoint e04813d4e7480c526912eb4d32bba510 hdfs://flink/flink/migration/savepoint56650 -Dyarn.application.id=application_1683808492336_1222报错内容 org.apache.flink.util.FlinkException: Triggering a savepoint for the job e04813d4e7480…

Excel 自动提取某一列不重复值

IFERROR(INDEX($A$1:$A$14,MATCH(0,COUNTIF($C$1:C1,$A$1:$A$14),0)),"")注意&#xff1a;C1要空置&#xff0c;从C2输入公式 参考&#xff1a; https://blog.csdn.net/STR_Liang/article/details/105182654 https://zhuanlan.zhihu.com/p/55219017?utm_id0

【Unity】【VR】详解Oculus Integration输入

【背景】 以下内容适用于Oculus Integration开发VR场景,也就是OVR打头的Scripts,不适用于OpenXR开发场景,也就是XR打头Scripts。 【详解】 OVR的Input相对比较容易获取。重点在于区分不同动作机制的细节效果。 OVR Input的按键存在Button和RawButton两个系列 RawButton…

vue-mixin

1.vue中&#xff0c;混入(mixin)是一种特殊的使用方式。一个混入对象可以包含任意的组件配置选项(data, props, components, watch,computed…)可以根据需求"封装"一些可复用的单元&#xff0c;并在使用时根据一定的策略合并到组件的选项中&#xff0c;使用时和组件自…

十六、【橡皮擦工具组】

文章目录 橡皮擦背景橡皮擦1. 一次取样2. 连续取样3. 取样背景色板 魔术橡皮擦 橡皮擦 橡皮擦跟我们平常生活中所用的橡皮擦是一样&#xff0c;它是将图层的内容擦除,只剩下空白部分。另外当我们按住Alt的键去擦除空白部分的时候&#xff0c;也可以将背景的部分显示出来。 另…

Maven系列第4篇:仓库详解

maven系列目标&#xff1a;从入门开始开始掌握一个高级开发所需要的maven技能。 这是maven系列第4篇。 整个maven系列的内容前后是有依赖的&#xff0c;如果之前没有接触过maven&#xff0c;建议从第一篇看起&#xff0c;本文尾部有maven完整系列的连接。 环境 maven3.6.1 …

小程序首页如何进行装修设置

小程序首页是展示给用户的第一屏&#xff0c;它的装修直接影响到用户对小程序的第一印象。小程序首页的设置在小程序管理员后台->页面设置->首页&#xff0c;下图是小程序首页默认的设置。 下图&#xff0c;是小程序首页的具体表现形式。下面具体解释小程序首页各个设置项…

Redis第四五六章 持久化事务主从复制

Redis ⽀持 RDB 和 AOF 两种持久化机制&#xff0c;持久化功能有效地避免因进程退出造成数据丢失问题&#xff0c; 当下次重启时利⽤之前持久化的⽂件即可实现数据恢复。 目录 第四章 持久化 4.1 RDB 4.1.1 触发机制 4.1.2 流程说明 4.1.3 RDB ⽂件的处理 4.1.4 RDB 的优…

Godot快速精通-从看懂英文文档开始-翻译插件

视频教程地址&#xff1a;https://www.bilibili.com/video/BV1t8411q7hw/ 大家好&#xff0c;我今天要和大家分享的是如何快速精通Godot&#xff0c;众所周知&#xff0c;一般一个开源项目都会有一个文档&#xff0c;对于有一定基础或者是理解能力强的同学&#xff0c;看文档比…

深度学习_1_基本语法

数据结构 代码&#xff1a; import torchx torch.arange(12)##产生长度为12的一维张量print(x)##X x.resize(3, 4)##被弃用##print(X)y torch.reshape(x, (3, 4))##修改向量为矩阵&#xff0c;一维变二维print(y)print(y.size())xx torch.zeros((2, 3, 4))##三维矩阵&…

前端-uniapp-开发指南

美团外卖微信小程序开发 uniapp-美团外卖微信小程序开发P1 成果展示P2外卖小程序后端&#xff0c;学习给小程序写http接口P3 主界面配置P4 首页组件拆分P13 外卖列表布局筛选组件商家 布局测试数据创建样式 请求商家外卖数据封装请求并发请求 uni-app框架调用https接口 开发小程…

《UnityShader入门精要》学习3

笛卡尔坐标系&#xff08;Cartesian Coordinate System&#xff09; 二维笛卡儿坐标系 一个二维的笛卡儿坐标系包含了两个部分的信息&#xff1a; 一个特殊的位置&#xff0c;即原点&#xff0c;它是整个坐标系的中心。两条过原点的互相垂直的矢量&#xff0c;即x轴和y轴。这…

Elasticsearch 和 Arduino:一起变得更好!

作者&#xff1a;Enrico Zimuel 使用 Arduino IoT 设备与 Elasticsearch 和 Elastic Cloud 进行通信的简单方法 在 Elastic&#xff0c;我们不断寻找简化搜索体验的新方法&#xff0c;并开始关注物联网世界。 来自物联网的数据收集可能非常具有挑战性&#xff0c;尤其是当我们…