JWT登录校验流程
jwt令牌的基本概念:
1. JWT(JSON Web Token)
- 定义:JWT 是一种开放标准(RFC 7519),用于在各方之间作为 JSON 对象安全地传输信息。它可以被验证和信任,因为它是数字签名的。
- 结构:JWT 有三个部分,每部分使用
.分隔:- Header:包含令牌的类型(通常是 JWT)和所使用的签名算法(如 HMAC SHA256 或 RSA)。
- Payload:包含声明(claims),即存储的信息,可以是用户信息、权限等。
- Signature:用于验证消息的真实性,以防止数据被篡改
和API签名认证的关系
这其实和API签名认证的过程有点像,API签名认证是在数据库字段中添加一个secretKey,然后根据前端传过来的字段拼起来根据相同的加密算法重新加密,再和数据库中的secretKey进行比对。
和传统的会话技术的对比
传统会话技术当你登录完成之后,在服务器端会生成一个session来记录你的登录态
当你登录之后,会给你的登录态设置一个值,下次访问其它接口的时候就直接检查你的登录态
传统的会话技术会将信息存储在服务器上,如果用户过多其实是有点怕存储不了的
但是传统的会话技术对用户的掌控能力更强,就是我可以直接在我的数据库中将session设置为失效,你直接就登录不了,不过对比于jwt,我们必须会设置一个过期时间,只有等过期时间过去了,你才不能登录。有利有弊。
整体的流程:
就是当你登录成功之后,系统会给你下发一个令牌,这个令牌肯定会比较复杂,拼接你的账号密码这些然后经过加密算法算出来一个字符串三个部分,三个部分就是我上面说的请求头,负载,签名。
这就是你的登录凭证了,当每次你需要调用其它接口的时候就需要这个登录凭证,说到这里也可以稍微提一下,就是我们每个方法之前都需要加一段这个判断逻辑嘛,其实可能不用,只需要配置一个全局拦截器就行。
我们从上面得流程中也能知道,我们需要在用户登录成功之后下发令牌:
先引入一个依赖:
<!-- 引入JWT令牌的依赖--><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.1</version></dependency>
代码:
controller层:
@Slf4j
@RestController
@CrossOrigin
@RequestMapping("/user")
public class UserController {@Resourceprivate NewsUserService newsUserService;@PostMapping("/login")public Result userLogin(@RequestBody UserLoginRequest userLoginRequest){log.info("登录接口:"+userLoginRequest);UserLoginVO userLoginVO = newsUserService.login(userLoginRequest);System.out.println(userLoginVO.getToken());return Result.ok(userLoginVO);}}
service层:
@Overridepublic UserLoginVO login(UserLoginRequest userLoginRequest) {//1:取出参数查询数据进行校验final String userName = userLoginRequest.getUserName();final String userPwd = userLoginRequest.getUserPwd();LambdaQueryWrapper<NewsUser> lambdaQueryWrapper = new LambdaQueryWrapper<>();lambdaQueryWrapper.eq(NewsUser::getUsername,userName);final NewsUser user = this.getOne(lambdaQueryWrapper);//2:判断这个user是否为空//todo 全局异常处理器if(user == null){return null;}//3:判断这个密码是否和数据库中加密的密码一致if(StringUtils.isBlank(user.getUser_pwd())|| !MD5Util.encrypt(userPwd).equals(user.getUser_pwd())){return null;}//4:下发令牌Map<String,Object> claims = new HashMap<>();claims.put("username",user.getUsername());claims.put("userpassword",user.getUser_pwd());final String jwtToken = JwtUtils.createJwtToken(claims);System.out.println("jwtToken"+jwtToken);final UserLoginVO userLoginVO = new UserLoginVO();userLoginVO.setUid(user.getUid());userLoginVO.setToken(jwtToken);return userLoginVO;}
代码整体逻辑:
首先上来就是对前端传过来得参数进行校验
接着再从数据库中查出是否有这个用户
都确定无误之后,就开始生成令牌,这里得生成令牌我用了一个工具类JwtUtils。
生成令牌之后就要给这个登录用户发放令牌,这所谓得发放令牌就是将这个token封装在这个响应成功得实体中。
下面是响应成功得封装:
@Data
public class UserLoginVO {/*** 用户id*/private Integer uid;/*** token*/private String token;
}
jwt工具类:
public class JwtUtils {private static String salt = "abcdefg";//盐值private static Long expire = 43200000L;//12小时(过期时间)public static String createJwtToken(Map<String,Object> claims){final String jwt = Jwts.builder().addClaims(claims).signWith(SignatureAlgorithm.HS256, salt).setExpiration(new Date(System.currentTimeMillis() + expire)).compact();return jwt;}}
生成令牌我们调用这个Jwts.build方法
里面构建三个东西
一个是你得账号密码这些你想进行加密得东西(用Map包装起来)
一个就是签名算法
还有一个是过期时间
小坑:
签名算法得key不能指定太短
JWT 生成token时报错:secret key byte array cannot be null or empty.
把签名算法得key或者盐值搞长点就行
我们现在已经把这个jwt令牌生成好了并且也下发给用户了,用户访问其它操作得时候需要带上这个令牌,下一步我们就需要去解析这个令牌了。
我们可以定义一个拦截器,我这里用得是AOP,其实我感觉用拦截器更好
拦截器和AOP得对比
拦截器:
- 拦截器通常用于请求处理链中,它会在控制器(Controller)方法被调用之前和之后执行。
- 拦截器是实现
HandlerInterceptor接口的类,通过 Spring MVC 的 DispatcherServlet 配置来注册。
AOP:
- AOP 通过切面(Aspect)定义横切逻辑,可以在多个地方复用。具体的切面在代码中使用注解标注,Spring 会解析这些注解并自动织入到相应的地方。
拦截器我在spingMVC那一篇中有写道
我们从上面的对比结果中可以得出,拦截器更多是用在Controller层的拦截,AOP是我们可以自己定义的。
再回顾我们的登录常见,我们是不是只需要在controller层进行一个拦截,就是在你调用其它方法的时候进行一个拦截就行。
不过话又说回来了,只要你AOP的范围选Controller层哪这个作用就和拦截器差不多了。
说了这么多,我下面的案例是用AOP,我顺带也复习一下。
@Slf4j
@Aspect
@Component
public class LoginCheckInterceptor {@Resourceprivate HttpServletRequest request;@Around("execution(* com.test.microheadline.controller..*(..))")public Object JwtTest(ProceedingJoinPoint point) throws Throwable {final String uri = request.getRequestURI();if(uri.contains("login")){return point.proceed();}String jwt = request.getHeader("token");System.out.println(request);System.out.println("JWT令牌:"+ jwt);final Claims claims = JwtUtils.parseJWT(jwt);return point.proceed();}
}
整体的代码逻辑:
定义一个切面类:@Aspect,并且交给IOC容器管理@Component
@Around("execution(* com.test.microheadline.controller..*(..))"),指定我们的作用范围(这里好像有更专业的词,我一时间文件了)是整个Controller
然后分析方法里面的具体逻辑:
首先我们需要从请求头中拿到jwt令牌
记住这个我们需要判断,这个路径是不是登录方法,如果是登录方法,我们都还没给他令牌,肯定
会报错
接着我们进行解析,也是调用jwt的工具类
public class JwtUtils {private static String salt = "abcdefg";//盐值private static Long expire = 43200000L;//12小时(过期时间)public static String createJwtToken(Map<String,Object> claims){final String jwt = Jwts.builder().addClaims(claims).signWith(SignatureAlgorithm.HS256, salt).setExpiration(new Date(System.currentTimeMillis() + expire)).compact();return jwt;}public static Claims parseJWT(String jwt){final Claims claims = Jwts.parser().setSigningKey(salt).parseClaimsJws(jwt).getBody();return claims;}}
解析之后放行:return point.proceed();
这个的point是AOP的连接点,proceed就是让这个点执行下一步流程,就是放行(这里可能有点像断点)
小坑:
我们在用Knife4j进行测试的时候,我们发送这个请求的时候,这个文档不会给我们自动带上这个jwt令牌,所以我们需要登录过后获取到这个令牌之后,在这个全局变量里面设置一下


相关文章:
JWT登录校验流程
jwt令牌的基本概念: 1. JWT(JSON Web Token) 定义:JWT 是一种开放标准(RFC 7519),用于在各方之间作为 JSON 对象安全地传输信息。它可以被验证和信任,因为它是数字签名的。结构&am…...
yarn安装和部署
文章目录 概述安装部署1.构建项目2.测试3.清理构建目录 小结 概述 yarn是一个快速、可靠和安全的JavaScript包管理工具,由Facebook开发。它被设计用来替代npm(Node Package Manager),尽管它与npm在很多方面兼容。yarn提供了以下一…...
Visual Studio的安装教程与使用方法
Visual Studio的安装教程与使用方法 一、Visual Studio的安装教程 1. 准备工作 确认系统要求: 在开始安装Visual Studio之前,请确保您的计算机满足Visual Studio的系统要求这。包括操作系统版本、内存、硬盘空间等。您可以在Visual Studio的官方网站…...
一键换装软件哪个好?6个换装工具让你秒变穿搭达人
#紫色跑道的city穿搭#火了,很多人都开始打卡各种紫色穿搭,展示自己的时尚态度。 但对于没有时间或金钱去精心搭配的我们来说,有没有一种更简单、更快捷的方式,让我们也能轻松跟上潮流呢? 当然有!今天&…...
【EtherCAT】Windows+Visual Studio配置SOEM主站——源码配置
目录 一、准备工作 1. Visual Studio 2022 2. Npcap 1.79 3. SOEM源码 二、源码部署 1. 新建Visual Studio工程 2. 创建文件夹 3. 创建主函数 4. 复制源代码 5. 删除无关项 6. 将soem源码添加进工程 7. 添加soem头文件 8. 配置头文件路径 9. 配置静态库和静态库路…...
GPTPDF深度解析:开源文档处理技术全攻略
GPTPDF深度解析:开源文档处理技术全攻略 在数字化信息时代,PDF文件因其稳定性和跨平台兼容性,已成为学术交流、技术文档和电子书籍等领域的首选格式。然而,PDF文档的处理和内容提取一直是一个难题。随着人工智能技术的飞速发展&a…...
网络学习:应用层DNS域名解析协议
目录 一、简介 二、工作流程 一、简介 DNS( Domain Name System)是“域名系统”的英文缩写,是一种组织成域层次结构的计算机和网络服务命名系统,它用于TCP/IP网络,它所提供的服务是用来将主机名和域名转换为IP地址的工作。 同时,DNS…...
7.怎么配置一个axios来拦截前后端请求
首先创建一个axios.js文件 导入我们所需要的依赖 import axios from "axios"; import Element from element-ui import router from "./router"; 设置请求头和它的类型和地址 注意先注释这个url,还没有解决跨域问题,不然会出现跨域 // axios.defaults.…...
Day17_1--AJAX学习之GET/POST传参
AJAX 简介 AJAX 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。其实AJAX就可以理解为就是JS。通过AJAX也就实现了前后端分离,前端只写页面,后端生成数据! 现在开始通过实例学习: 1--GET传参 <!…...
golang国内proxy设置
go env -w GOPROXYhttps://goproxy.cn,direct经常使用的两个, goproxy.cn 和 goproxy.io 连接分别是 https://goproxy.cn https://goproxy.io 如果遇到某些包下载不下来的情况,可尝试更换数据源 更推荐使用https://goproxy.cn 速度快,缓存的包多 提醒…...
全网最适合入门的面向对象编程教程:31 Python的内置数据类型-对象Object和类型Type
全网最适合入门的面向对象编程教程:31 Python 的内置数据类型-对象 Object 和类型 Type 摘要: Python 中的对象和类型是一个非常重要的概念。在 Python 中,一切都是对象,包括数字、字符串、列表等,每个对象都有自己的类型。 原文链接: Fre…...
【mongodb】mongodb副本集的搭建和使用
本站以分享各种运维经验和运维所需要的技能为主 《python零基础入门》:python零基础入门学习 《python运维脚本》: python运维脚本实践 《shell》:shell学习 《terraform》持续更新中:terraform_Aws学习零基础入门到最佳实战 《k8…...
Java后端面试复习7.24
lock加锁解锁尝试获取锁方法lock底层基于什么实现lock和lock的底层实现分别面向什么用户lock和synchronized异同如何选择合适的锁ReentrantLock如何实现冲入内部类三个公平和非公平获取锁怎么实现的RL默认公平还是非公平,构造参数ReentrantRedaWriteLock的特性什么是…...
前端 HTML 概述
目录 1. HTML概述 1.1 超文本标记语言 1.2 标签 2. HTML 解析与编辑 2.1 解析与访问 2.2 编辑 html文件 1. HTML概述 HTML( Hyper Text Markup Language:超文本标记语言 ):主要用于网页主体结构的搭建,在网页上…...
探索Thymeleaf:用动态Web模板引擎打造吸引人的用户界面(SpringBoot的html详解)
什么是Thymeleaf? Thymeleaf是一个用于Web和独立环境的现代服务器端Java模板引擎,用于处理XML/XHTML/HTML5内容。它特别适合基于Spring框架的Web应用程序,因为它提供了与Spring MVC的出色集成。Thymeleaf以其自然的模板语法和强大的数据绑定…...
视频教程 - 自研Vue3 Tree组件高级功能:虚拟滚动新增节点实现自动滚动
感谢小伙伴们对本套自研vue3 tree组件教程的关注,在前一篇媲美Element Plus JuanTree终极实战:虚拟滚动的功能演示中发现了小bug,特地整理了相关录屏来说明怎么一步步解决bug的,来回馈小伙伴们的支持。 Tree组件高级功能ÿ…...
职业生涯阶段总结3:转眼毕业三年
不知不觉,科班毕业三年多了,也换了三个单位了; 个人软件开发的理论和技术能力确实比以前刚出来的时候,强了不少; 在行情越发下滑的形势,似乎只有进大厂才能拿到不错的收入,但是大厂的压力也是比…...
项目经理面试总结
先上结论:每个公司问的问题侧重点都不太一样,五花八门,评判标准也不一样,目前我能感觉到的就是自己需要很了解项目,也就是工作过程中经常做出总结,需要你经常去思考,包括对内和对外的思考。 自我…...
(免费领源码)java#springboot#mysql大学校园旧物捐赠网站 25109-计算机毕业设计项目选题推荐
摘 要 在网络信息的时代,众多的软件被开发出来,给用户带来了很大的选择余地,而且人们越来越追求更个性的需求。在这种时代背景下,企业只能以用户为导向,按品种分类规划,以产品的持续创新作为企业最重要的竞…...
Java 设计模式之单例模式
Java 设计模式之单例模式 单例模式是一种创建型设计模式,它确保一个类只有一个实例,并提供了一种访问该实例的全局方法。这种模式有助于确保系统中的某些组件只有一个实例,并提供了一种方便的方法来访问该实例。 更多设计模式请参考&#x…...
无极调速数控车床主轴箱装配图CAD图纸
无极调速数控车床主轴箱装配图CAD图纸是机械设计与制造领域的重要学习资料,其核心作用在于通过标准化图形语言精确描述主轴箱各部件的装配关系与空间布局。主轴箱作为数控车床的动力核心,其结构设计的合理性直接影响加工精度与运行稳定性。装配图通过分解…...
Yii框架的模型怎么使用UUID做主键_覆盖primaryKey和behaviors】
在Yii框架中使用UUID作为主键覆盖primaryKey方法在模型中声明主键字段为UUID,需要覆盖primaryKey()方法。默认情况下Yii假设主键是自增整数,修改为返回UUID字段名:public static function primaryKey() {return [id]; // 假设UUID字段名为id …...
从 transactional contract 读懂 ABAP 事务边界:RAP、Controlled SAP LUW 与一致性设计实践
在 SAP 新一代开发模型里,transactional contract 并不是一个只存在于文档角落里的术语,它实际上定义了 ABAP 代码在事务运行过程中能做什么、不能做什么。这个机制的意义,不只是限制开发者的自由,而是把事务一致性从靠经验推进到靠框架与规则共同保障。SAP 官方将它定义为…...
抖音数据抓取第一步:雷电模拟器3.107版保姆级配置指南(含Xposed框架安装)
抖音数据抓取第一步:雷电模拟器3.107版保姆级配置指南(含Xposed框架安装) 如果你正准备踏入移动应用数据分析或自动化测试的领域,那么一个稳定、可控的安卓模拟器环境就是你不可或缺的“数字沙盒”。无论是为了研究热门应用的交互…...
PyMuPDF实战教程:10个案例掌握PDF批量处理与自动化技巧
PyMuPDF实战教程:10个案例掌握PDF批量处理与自动化技巧 【免费下载链接】PyMuPDF PyMuPDF is a high performance Python library for data extraction, analysis, conversion & manipulation of PDF (and other) documents. 项目地址: https://gitcode.com/g…...
二进制安装Nginx——详细
☆ Nginx概述Nginx (engine x) 是一个高性能的HTTP和反向代理Web服务器,同时也提供了IMAP/POP3/SMTP等邮件服务。Nginx是由伊戈尔赛索耶夫为俄罗斯访问量第二的Rambler.ru站点(俄文:Рамблер)开发的,第一个公开版…...
Windows环境下高效部署CosyVoice:从配置优化到生产环境实战
在Windows平台上部署语音服务,尤其是像CosyVoice这样功能丰富的项目,确实是个技术活。很多朋友都卡在了环境配置、性能调优这些环节,感觉比写业务逻辑还头疼。今天,我就结合自己最近在生产环境折腾CosyVoice的经历,跟大…...
MiniCPM-V-2_6农业植保图识别:病虫害症状+防治方案生成
MiniCPM-V-2_6农业植保图识别:病虫害症状防治方案生成 1. 引言:AI视觉技术如何改变农业植保 想象一下这样的场景:一位农民在田间发现作物叶片出现异常斑点,拿出手机拍张照片,几秒钟后就能获得准确的病虫害诊断和具体…...
鸿蒙(HarmonyOS)应用开发实战:从零构建登录页UI
1. 环境准备与项目创建:迈出第一步 嘿,朋友们,我是老张,一个在移动开发领域摸爬滚打了十来年的老码农。最近几年,我花了大量时间在鸿蒙生态上,看着它从无到有,感觉就像当年看着安卓和iOS成长一样…...
FFmpeg与Nvidia硬件加速实战:从安装到性能优化全解析
1. 为什么你需要Nvidia硬件加速?从CPU到GPU的跨越 如果你处理过视频转码,尤其是高分辨率、高帧率的4K甚至8K素材,一定对漫长的等待时间印象深刻。我刚开始做视频处理时,用一台配置不错的CPU服务器转一段10分钟的1080p视频…...
