SpringBoot集成JWT token实现权限验证
JWT=JSON Web Token
1. JWT的组成
JWT==Header,Payload,Signature==>abc.def.xyz


地址:JSON Web Tokens - jwt.er
1.1 Header
Header:标头。
两个组成部分:令牌的类型(JWT)和所使用的签名算法,经过Base64 Url编码后形成的JWT的第一部分。
{"type":"JWT","alg":"HS256"
}
1.2 Payload
Payload---有效负载。存放用户自定义消息
注意点:是以明文的形式进行展示,以Base64进行编码。
{“sub":"123","name":"jon","admin":true
}
1.3 Signature
signature--签名。使用标头的算法和私钥对第一部分和第二部分进行加密,通过Base64 Url编码后形成JWT的第三部分。
var encodeString =base64UrlEncode(header)+"."+base64UrlEncode(payload);
var signature=HMACSHA356(encodeString,secret);
2.JWT的基本使用
1.导入pom JWT依赖
JDK1.8以下的加入JWT依赖即可
<!--JWT--><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.1</version></dependency>
JDK1.8以上的加上其他
<!--JWT--><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.1</version></dependency><dependency><groupId>javax.xml.bind</groupId><artifactId>jaxb-api</artifactId><version>2.3.0</version></dependency><dependency><groupId>com.sun.xml.bind</groupId><artifactId>jaxb-impl</artifactId><version>2.3.0</version></dependency><dependency><groupId>com.sun.xml.bind</groupId><artifactId>jaxb-core</artifactId><version>2.3.0</version></dependency>
2.创建JWT
//毫秒private long time=1000*60*60*24;//签名private String signature="admin";/*JWT加密*/@Testpublic void jwt(){//构建JWT对象:Jwts.builder()JwtBuilder jwtBuilder = Jwts.builder();String jwtToken = jwtBuilder//header:头部.setHeaderParam("typ", "JWT").setHeaderParam("alg", "HS256")//payload:载荷.claim("username", "tom").claim("role", "admin").setSubject("admin-test")//有效时间===>一天=当前时间+24小时//获得当前的系统时间:System.currentTimeMillis().setExpiration(new Date(System.currentTimeMillis() + time))//设置id字段.setId(UUID.randomUUID().toString())//signature:签名//注意点:这个签名算法要与前面的算法一致//设置加密算法和签名.signWith(SignatureAlgorithm.HS256, signature)//将前面3个重要信息拼接起来,使用”."来连接.compact();System.out.println(jwtToken);}
3.验证JWT
@Test/*验证JWT*/public void checkJwt(){String token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6InRvbSIsInJvbGUiOiJhZG1pbiIsInN1YiI6ImFkbWluLXRlc3QiLCJleHAiOjE2OTM2MzgzMDMsImp0aSI6ImU5ZjY3ZjBhLWE0NTAtNGYzYy1hYTY3LTU3ZGMwOWRjMDM4ZCJ9.FxA5c91E2bk2KW1rdMo8jlmClXgn7r2mVSaXs19Qzzk";//Jwts.parser():解析JwtParser jwtParser = Jwts.parser();//验证该token是否符合JWT规则boolean result = Jwts.parser().isSigned(token);System.out.println(result);//true}
4.解析JWT
@Test/*解析JWT*/public void parseJwt(){String token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6InRvbSIsInJvbGUiOiJhZG1pbiIsInN1YiI6ImFkbWluLXRlc3QiLCJleHAiOjE2OTM2MzgzMDMsImp0aSI6ImU5ZjY3ZjBhLWE0NTAtNGYzYy1hYTY3LTU3ZGMwOWRjMDM4ZCJ9.FxA5c91E2bk2KW1rdMo8jlmClXgn7r2mVSaXs19Qzzk";//获取JWT的解析对象JwtParser jwtParser = Jwts.parser();//通过signature对token进行签名,解开//parseClaimsJws:将JWT转换为key-value的形式,通过key来获取对应的value//Jws<Claims>:类似于Map集合Jws<Claims> claimsJws = jwtParser.setSigningKey(signature).parseClaimsJws(token);//获取Jws对象中的数据:get(key)表示根据key来获取value//相当于将header和payload封装为一个claimsClaims claims = claimsJws.getBody();//存储的是用户保存的数据Object username = claims.get("username");System.out.println(username);Object role = claims.get("role");System.out.println(role);String id = claims.getId();System.out.println(id);//签名String subject = claims.getSubject();System.out.println(subject);//有效期Date time = claims.getExpiration();System.out.println(time);}
3.SpringBoot + vue +JWT
1.导入pom JWT依赖
JDK1.8以下的加入JWT依赖即可
<!--JWT--><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.1</version></dependency>
JDK1.8以上的还要加上以下依赖
<!--JWT--><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.1</version></dependency><dependency><groupId>javax.xml.bind</groupId><artifactId>jaxb-api</artifactId><version>2.3.0</version></dependency><dependency><groupId>com.sun.xml.bind</groupId><artifactId>jaxb-impl</artifactId><version>2.3.0</version></dependency><dependency><groupId>com.sun.xml.bind</groupId><artifactId>jaxb-core</artifactId><version>2.3.0</version></dependency><dependency><groupId>javax.activation</groupId><artifactId>activation</artifactId><version>1.1.1</version></dependency>
2.导入工具类
public class JwtUtil {//毫秒private static long time=1000*60*60*24;//签名private static String signature="admin";public static String createToken(){//构建JWT对象:Jwts.builder()JwtBuilder jwtBuilder = Jwts.builder();String jwtToken=jwtBuilder//header.setHeaderParam("typ", "JWT").setHeaderParam("alg", "HS256")//payload.claim("username", "admin").claim("role", "admin").setSubject("admin-test")//有效时间===>一天=当前时间+24小时//获得当前的系统时间:System.currentTimeMillis().setExpiration(new Date(System.currentTimeMillis()+time)).setId(UUID.randomUUID().toString())//signature//注意点:这个签名算法要与前面的算法一致.signWith(SignatureAlgorithm.HS256,signature)//将前面3个重要信息拼接起来.compact();return jwtToken;}
}
3.在后台解决跨域问题
@Configuration//配置类
public class CoreConfiguration implements WebMvcConfigurer {@Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping("/**")//所有接口.allowCredentials(true)//是否发送Cookie.allowedOriginPatterns("*")//支持域.allowedMethods("GET","POST","PUT","DELETE")//支持方法.allowedHeaders("*").exposedHeaders("*");}
}
4.前台登录界面

5.前端代码
methods:{handleSubmit(){this.$refs.ruleForm.validate((valid)=>{if(valid){let _this=thisaxios.get("http://localhost:8080/login",{param:_this.ruleForm}).then(function (response){console.log(response.data)})}})}}

6.进行路由跳转,并且将用户信息存到本地存储中
JSON.stringify-->将JSON转换为字符串
handleSubmit(){this.$refs.ruleForm.validate((valid)=>{if(valid){let _this=thisaxios.get("http://localhost:8080/login",{param:_this.ruleForm})./*带着用户输入的用户名和密码*/then(function (response){console.log(response.data)//如果data不为空,则表示登录成功if(response.data!=null){//使用localStorage//将JSON转换为字符串localStorage.setItem('access-admin',JSON.stringify(response.data))//跳转到首页_this.$router.replace({path:"/"})}})}})}
7.将用户信息展示到页面中
JSON.parse--->将字符串转换为JSON
<template>
<div>欢迎回来:{{admin.username}}
</div>
</template>data(){return{admin:''}},created() {
//获取数据this.admin=JSON.parse(window.localStorage.getItem("access-admin"));},
8.添加验证用户信息是否存在【在路由中写】
/router/index.js
router.beforeEach((to,from,next)=>{if(to.path.startsWith('/login')){window.localStorage.removeItem('access-admin')next()}else {let admin=JSON.parse(window.localStorage.getItem('access-admin'))if(!admin){next({path:'/login'})}else {//校验token合法性axios({url:'http://localhost:8080/checkeToken',method:'get',headers:{token:admin.token}}).then((response)=>{if(!response.data){console.log("校验失败");next({path:'/error'})}})}}
})

9.后端验证Token方法
UserController
/*** 验证token方法*/@GetMapping("/checkToken")public Boolean checkToken(HttpServletRequest request){//因为前端是将数据存储在header,所以我们要是有getHeaderString token = request.getHeader("token");return JwtUtil.checkToken(token);}
JwtUtil
/*** 校验token是否正确*/public static boolean checkToken(String token){if (token==null){return false;}try {//解析Jws<Claims> claimsJws = Jwts.parser().setSigningKey(signature).parseClaimsJws(token);}catch (Exception e){e.printStackTrace();}return true;}
4.Springboot+JWT
User
@Data
public class User {private String username;private String password;private String token;
}
UserController:生成JWT令牌
public class UserController {private final String USERNAME = "admin";private final String PASSWORD = "123123";@GetMapping("/login")public User login(User user){//判断是否正确if(USERNAME.equals(user.getUsername()) && PASSWORD.equals(user.getPassword())){//添加token;token保存到user对象//定义一个工具类,将生成JWTuser.setToken(JwtUtil.createToken());return user;}return null;}
}
JwtUtil:生成JWT令牌
public class JwtUtil {//毫秒private static long time=1000*60*60*24;//签名private static String signature="admin";public static String createToken(){//构建JWT对象:Jwts.builder()JwtBuilder jwtBuilder = Jwts.builder();String jwtToken=jwtBuilder//header.setHeaderParam("typ", "JWT").setHeaderParam("alg", "HS256")//payload.claim("username", "admin").claim("role", "admin").setSubject("admin-test")//有效时间===>一天=当前时间+24小时//获得当前的系统时间:System.currentTimeMillis().setExpiration(new Date(System.currentTimeMillis()+time)).setId(UUID.randomUUID().toString())//signature//注意点:这个签名算法要与前面的算法一致.signWith(SignatureAlgorithm.HS256,signature)//将前面3个重要信息拼接起来.compact();return jwtToken;}
}
【前端直接传递token】
JwtUtil:验证JWT是否过期
/*** 校验token是否过期*/public static boolean checkToken(String token){if (token==null || token==""){return false;//false表示令牌过期}try {//拿到JWT对象Jws<Claims> claimsJws = Jwts.parser().setSigningKey(signature).parseClaimsJws(token);}catch (Exception e){e.printStackTrace();}return true;}
UserController:验证JWT是否过期
/*** 验证token是否过期:前端传递token*/@GetMapping("/checkToken")public Boolean checkToken(String token){return JwtUtil.checkToken(token);}
【将Token放入请求头中,使用request】
JwtUtil:验证JWT是否过期
/*** 校验token是否过期*/public static boolean checkToken(String token){if (token==null || token==""){return false;//false表示令牌过期}try {//拿到JWT对象Jws<Claims> claimsJws = Jwts.parser().setSigningKey(signature).parseClaimsJws(token);}catch (Exception e){e.printStackTrace();}return true;}
UserController:验证JWT是否过期
/*** 验证token是否过期:前端将数据封装在请求头中* @param request* @return*/public boolean checkToken(HttpServletRequest request){//getHeader中的key要与前端通过一致String token = request.getHeader("token");//key-->tokenreturn JwtUtil.checkToken(token);}
解决跨域问题
参考:SpringBoot跨域请求的问题_m0_63077733的博客-CSDN博客
@Configuration
public class CorsConfig implements WebMvcConfigurer {@Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping("/**") // 所有接口.allowCredentials(true) // 是否发送 Cookie.allowedOriginPatterns("*") // 支持域.allowedMethods("GET", "POST", "PUT", "DELETE") // 支持方法.allowedHeaders("*").exposedHeaders("*");}
}
拦截器实现Token验证
@Configuration
public class TokenInterceptor implements HandlerInterceptor {//在请求处理方法被调用之前被调用@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {//前提:token放在请求头中String token = request.getHeader("token");if (!JwtUtil.checkToken(token)) {return false;//验证失败}return true;}
}
相关文章:
SpringBoot集成JWT token实现权限验证
JWTJSON Web Token 1. JWT的组成 JWTHeader,Payload,Signature>abc.def.xyz 地址:JSON Web Tokens - jwt.er 1.1 Header Header:标头。 两个组成部分:令牌的类型(JWT)和所使用的签名算法,经过Base64 Url编码后形成…...
算法通关村第11关【青铜】| 位运算基础
1.数字在计算机中的表示 原码、反码和补码都是计算机中用于表示有符号整数的方式。它们的使用旨在解决计算机硬件中的溢出和算术运算问题。 原码(Sign-Magnitude): 原码最简单,它的表示方式是用最高位表示符号位,0表示…...
无涯教程-Android - RadioGroup函数
RadioGroup类用于单选按钮集。 如果我们选中属于某个单选按钮组的一个单选按钮,它将自动取消选中同一组中以前选中的任何单选按钮。 RadioGroup属性 以下是与RadioGroup控制相关的重要属性。您可以查看Android官方文档以获取属性的完整列表以及可以在运行时更改这些属性的相关…...
降噪音频转录 Krisp: v1.40.7 Crack
主打人工智能降噪服务的初创公司「Krisp」近期宣布推出音频转录功能,能对电话和视频会议进行实时设备转录。该软件还整合的ChatGPT,以便快速总结内容,开放测试版于今天上线。 随着线上会议越来越频繁,会议转录已成为团队工作的重…...
基于React实现:弹窗组件与Promise的有机结合
背景 弹窗在现代应用中是最为常见的一种展示信息的形式,二次确认弹窗是其中最为经典的一种。当我们在React,Vue这种数据驱动视图的前端框架中渲染弹窗基本是固定的使用形式。 使用方式:创建新的弹窗组件,在需要弹窗的地方引用并…...
docker使用(一)生成,启动,更新(容器暂停,删除,再生成)
docker使用(一) 编写一个 Dockerfile构建镜像构建失败构建成功 运行镜像运行成功 修改代码后再次构建请不要直接进行构建,要将原有的旧容器删除或暂停停止成功删除成功再次构建且构建成功! 要创建一个镜像,你可以按照以…...
用Qt自制一个小闹钟
小闹钟 功能 当按下启动按钮时,停止按钮可用,启动按钮不可用,闹钟无法设置,无法输入自定义内容 当按下停止按钮时,暂停播报,启动按钮可用,闹钟可以设置,可以输入自定义内容 .pro文…...
Vue2.0/Vue3.0使用xlsx+xlsx-style实现导出Excel文件
一、依赖导入 1、Vue2 Webpack构建的 npm i xlsx npm i xlsx-style npm i file-saver同时修改以下: 解决 Can’t resolve ‘./cptable’ in ‘…’ 的问题,在 vue.config.js 文件中加入该配置 module.exports {externals: {./cptable: var cptable}…...
【Kafka系列】(一)Kafka入门
有的时候博客内容会有变动,首发博客是最新的,其他博客地址可能会未同步,认准https://blog.zysicyj.top 首发博客地址 系列文章地址 Kafka是什么? 一句话概括:「Apache Kafka 是一款开源的消息引擎系统」 什么是消息引擎系统&#…...
外包干了2个月,技术退步明显了...
先说一下自己的情况,大专生,19年通过校招进入湖南某软件公司,干了接近4年的功能测试,今年8月份,感觉自己不能够在这样下去了,长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试…...
python实现语音识别
1. 首先安装依赖库 pip install playsound # 该库用于播放音频文件 pip install speech_recognition # 该库用于语音识别 pip install PocketSphinx # 语音识别模块中只有sphinx支持离线的,使用该模块需单独安装 pip install pyttsx3 # 该库用于将文本转换为语音播…...
java八股文面试[多线程]——线程的状态
5种状态一般是针对传统的线程状态来说(操作系统层面) 6种状态:Java中给线程准备的 NEW:Thread对象被创建出来了,但是还没有执行start方法。 RUNNABLE:Thread对象调用了start方法,就为RUNNABLE状…...
Go学习[合集]
文章目录 Go学习-Day1Go学习-Day2标识符变量基础语法字符串类型类型转换string和其他基本类型转换其他类型转stringstring转其他类型 指针类型运算符标准IO分支语句 Go学习-Day3循环语句函数声明init函数匿名函数闭包defer Go学习-Day4函数值传递,引用传递常用的函数…...
代码随想录算法训练营第42天 | ● 01背包问题,你该了解这些! ● 01背包问题,你该了解这些! 滚动数组 ● 416. 分割等和子集
文章目录 前言一、01背包问题,你该了解这些!二、01背包问题,你该了解这些! 滚动数组三、416. 分割等和子集总结 前言 01背包 一、01背包问题,你该了解这些! 确定dp数组以及下标的含义 对于背包问题&#x…...
解决DNS服务器未响应错误的方法
当你将设备连接到家庭网络或具有互联网接入功能的Wi-Fi热点时,由于各种原因,互联网连接可能无法正常工作。本文中的说明适用于Windows 10、Windows 8和Windows 7。 无法连接到DNS服务器的原因 故障的一类与域名系统有关,域名系统是世界各地互联网提供商使用的分布式名称…...
SpringBoot的HandlerInterceptor拦截器使用方法
一、创建拦截器 通过实现HandlerInterceptor接口创建自己要使用的拦截器 import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.…...
java 常用 jar 包
1 Lombok 是一个 java 类库,它利用注解方式自动生成 java bean 中 getter、setter、equals 等方法,还能自动生成 logger、toString、hashCode、builder 等 日志相关变量、Object 类方法或设计模式相关的方法,能够让你的 代码更简洁࿰…...
C#面试十问
1:C#中变量类型分为哪两种?它们的区别是什么?2:Class和Struct的区别?3:C#中类的修饰符和类成员的修饰符有哪些?4:面向对象的三个特征(特点)是什么?…...
Day 41 动态规划part03 : 343. 整数拆分 96.不同的二叉搜索树
96. 不同的二叉搜索树 给你一个整数 n ,求恰由 n 个节点组成且节点值从 1 到 n 互不相同的 二叉搜索树 有多少种?返回满足题意的二叉搜索树的种数。 示例 1: 输入:n 3 输出:5示例 2: 输入:n 1…...
四轴飞行器的电池研究(MatlabSimulink仿真)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...
RestClient
什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端,它允许HTTP与Elasticsearch 集群通信,而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级ÿ…...
【OSG学习笔记】Day 18: 碰撞检测与物理交互
物理引擎(Physics Engine) 物理引擎 是一种通过计算机模拟物理规律(如力学、碰撞、重力、流体动力学等)的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互,广泛应用于 游戏开发、动画制作、虚…...
高危文件识别的常用算法:原理、应用与企业场景
高危文件识别的常用算法:原理、应用与企业场景 高危文件识别旨在检测可能导致安全威胁的文件,如包含恶意代码、敏感数据或欺诈内容的文档,在企业协同办公环境中(如Teams、Google Workspace)尤为重要。结合大模型技术&…...
Neo4j 集群管理:原理、技术与最佳实践深度解析
Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...
成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战
在现代战争中,电磁频谱已成为继陆、海、空、天之后的 “第五维战场”,雷达作为电磁频谱领域的关键装备,其干扰与抗干扰能力的较量,直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器,凭借数字射…...
C++八股 —— 单例模式
文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全(Thread Safety) 线程安全是指在多线程环境下,某个函数、类或代码片段能够被多个线程同时调用时,仍能保证数据的一致性和逻辑的正确性…...
大数据学习(132)-HIve数据分析
🍋🍋大数据学习🍋🍋 🔥系列专栏: 👑哲学语录: 用力所能及,改变世界。 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言Ǵ…...
短视频矩阵系统文案创作功能开发实践,定制化开发
在短视频行业迅猛发展的当下,企业和个人创作者为了扩大影响力、提升传播效果,纷纷采用短视频矩阵运营策略,同时管理多个平台、多个账号的内容发布。然而,频繁的文案创作需求让运营者疲于应对,如何高效产出高质量文案成…...
快刀集(1): 一刀斩断视频片头广告
一刀流:用一个简单脚本,秒杀视频片头广告,还你清爽观影体验。 1. 引子 作为一个爱生活、爱学习、爱收藏高清资源的老码农,平时写代码之余看看电影、补补片,是再正常不过的事。 电影嘛,要沉浸,…...
