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

JWT登录校验流程

jwt令牌的基本概念:

1. JWT(JSON Web Token)
  • 定义:JWT 是一种开放标准(RFC 7519),用于在各方之间作为 JSON 对象安全地传输信息。它可以被验证和信任,因为它是数字签名的。
  • 结构:JWT 有三个部分,每部分使用 . 分隔:
    1. Header:包含令牌的类型(通常是 JWT)和所使用的签名算法(如 HMAC SHA256 或 RSA)。
    2. Payload:包含声明(claims),即存储的信息,可以是用户信息、权限等。
    3. 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令牌的基本概念&#xff1a; 1. JWT&#xff08;JSON Web Token&#xff09; 定义&#xff1a;JWT 是一种开放标准&#xff08;RFC 7519&#xff09;&#xff0c;用于在各方之间作为 JSON 对象安全地传输信息。它可以被验证和信任&#xff0c;因为它是数字签名的。结构&am…...

yarn安装和部署

文章目录 概述安装部署1.构建项目2.测试3.清理构建目录 小结 概述 yarn是一个快速、可靠和安全的JavaScript包管理工具&#xff0c;由Facebook开发。它被设计用来替代npm&#xff08;Node Package Manager&#xff09;&#xff0c;尽管它与npm在很多方面兼容。yarn提供了以下一…...

Visual Studio的安装教程与使用方法

Visual Studio的安装教程与使用方法 一、Visual Studio的安装教程 1. 准备工作 确认系统要求&#xff1a; 在开始安装Visual Studio之前&#xff0c;请确保您的计算机满足Visual Studio的系统要求这。包括操作系统版本、内存、硬盘空间等。您可以在Visual Studio的官方网站…...

一键换装软件哪个好?6个换装工具让你秒变穿搭达人

#紫色跑道的city穿搭#火了&#xff0c;很多人都开始打卡各种紫色穿搭&#xff0c;展示自己的时尚态度。 但对于没有时间或金钱去精心搭配的我们来说&#xff0c;有没有一种更简单、更快捷的方式&#xff0c;让我们也能轻松跟上潮流呢&#xff1f; 当然有&#xff01;今天&…...

【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深度解析&#xff1a;开源文档处理技术全攻略 在数字化信息时代&#xff0c;PDF文件因其稳定性和跨平台兼容性&#xff0c;已成为学术交流、技术文档和电子书籍等领域的首选格式。然而&#xff0c;PDF文档的处理和内容提取一直是一个难题。随着人工智能技术的飞速发展&a…...

网络学习:应用层DNS域名解析协议

目录 一、简介 二、工作流程 一、简介 DNS( Domain Name System)是“域名系统”的英文缩写&#xff0c;是一种组织成域层次结构的计算机和网络服务命名系统&#xff0c;它用于TCP/IP网络&#xff0c;它所提供的服务是用来将主机名和域名转换为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 是一种在无需重新加载整个网页的情况下&#xff0c;能够更新部分网页的技术。其实AJAX就可以理解为就是JS。通过AJAX也就实现了前后端分离&#xff0c;前端只写页面&#xff0c;后端生成数据&#xff01; 现在开始通过实例学习&#xff1a; 1--GET传参 <!…...

golang国内proxy设置

go env -w GOPROXYhttps://goproxy.cn,direct经常使用的两个, goproxy.cn 和 goproxy.io 连接分别是 https://goproxy.cn https://goproxy.io 如果遇到某些包下载不下来的情况&#xff0c;可尝试更换数据源 更推荐使用https://goproxy.cn 速度快&#xff0c;缓存的包多 提醒…...

全网最适合入门的面向对象编程教程:31 Python的内置数据类型-对象Object和类型Type

全网最适合入门的面向对象编程教程&#xff1a;31 Python 的内置数据类型-对象 Object 和类型 Type 摘要&#xff1a; Python 中的对象和类型是一个非常重要的概念。在 Python 中,一切都是对象,包括数字、字符串、列表等,每个对象都有自己的类型。 原文链接&#xff1a; Fre…...

【mongodb】mongodb副本集的搭建和使用

本站以分享各种运维经验和运维所需要的技能为主 《python零基础入门》&#xff1a;python零基础入门学习 《python运维脚本》&#xff1a; python运维脚本实践 《shell》&#xff1a;shell学习 《terraform》持续更新中&#xff1a;terraform_Aws学习零基础入门到最佳实战 《k8…...

Java后端面试复习7.24

lock加锁解锁尝试获取锁方法lock底层基于什么实现lock和lock的底层实现分别面向什么用户lock和synchronized异同如何选择合适的锁ReentrantLock如何实现冲入内部类三个公平和非公平获取锁怎么实现的RL默认公平还是非公平&#xff0c;构造参数ReentrantRedaWriteLock的特性什么是…...

前端 HTML 概述

目录 1. HTML概述 1.1 超文本标记语言 1.2 标签 2. HTML 解析与编辑 2.1 解析与访问 2.2 编辑 html文件 1. HTML概述 HTML&#xff08; Hyper Text Markup Language&#xff1a;超文本标记语言 &#xff09;&#xff1a;主要用于网页主体结构的搭建&#xff0c;在网页上…...

探索Thymeleaf:用动态Web模板引擎打造吸引人的用户界面(SpringBoot的html详解)

什么是Thymeleaf&#xff1f; Thymeleaf是一个用于Web和独立环境的现代服务器端Java模板引擎&#xff0c;用于处理XML/XHTML/HTML5内容。它特别适合基于Spring框架的Web应用程序&#xff0c;因为它提供了与Spring MVC的出色集成。Thymeleaf以其自然的模板语法和强大的数据绑定…...

视频教程 - 自研Vue3 Tree组件高级功能:虚拟滚动新增节点实现自动滚动

感谢小伙伴们对本套自研vue3 tree组件教程的关注&#xff0c;在前一篇媲美Element Plus JuanTree终极实战&#xff1a;虚拟滚动的功能演示中发现了小bug&#xff0c;特地整理了相关录屏来说明怎么一步步解决bug的&#xff0c;来回馈小伙伴们的支持。 Tree组件高级功能&#xff…...

职业生涯阶段总结3:转眼毕业三年

不知不觉&#xff0c;科班毕业三年多了&#xff0c;也换了三个单位了&#xff1b; 个人软件开发的理论和技术能力确实比以前刚出来的时候&#xff0c;强了不少&#xff1b; 在行情越发下滑的形势&#xff0c;似乎只有进大厂才能拿到不错的收入&#xff0c;但是大厂的压力也是比…...

项目经理面试总结

先上结论&#xff1a;每个公司问的问题侧重点都不太一样&#xff0c;五花八门&#xff0c;评判标准也不一样&#xff0c;目前我能感觉到的就是自己需要很了解项目&#xff0c;也就是工作过程中经常做出总结&#xff0c;需要你经常去思考&#xff0c;包括对内和对外的思考。 自我…...

(免费领源码)java#springboot#mysql大学校园旧物捐赠网站 25109-计算机毕业设计项目选题推荐

摘 要 在网络信息的时代&#xff0c;众多的软件被开发出来&#xff0c;给用户带来了很大的选择余地&#xff0c;而且人们越来越追求更个性的需求。在这种时代背景下&#xff0c;企业只能以用户为导向&#xff0c;按品种分类规划&#xff0c;以产品的持续创新作为企业最重要的竞…...

Java 设计模式之单例模式

Java 设计模式之单例模式 单例模式是一种创建型设计模式&#xff0c;它确保一个类只有一个实例&#xff0c;并提供了一种访问该实例的全局方法。这种模式有助于确保系统中的某些组件只有一个实例&#xff0c;并提供了一种方便的方法来访问该实例。 更多设计模式请参考&#x…...

【论文阅读28】-CNN-BiLSTM-Attention-(2024)

本文把滑坡位移序列拆开、筛优质因子&#xff0c;再用 CNN-BiLSTM-Attention 来动态预测每个子序列&#xff0c;最后重构出总位移&#xff0c;预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵&#xff08;S…...

JVM暂停(Stop-The-World,STW)的原因分类及对应排查方案

JVM暂停(Stop-The-World,STW)的完整原因分类及对应排查方案,结合JVM运行机制和常见故障场景整理而成: 一、GC相关暂停​​ 1. ​​安全点(Safepoint)阻塞​​ ​​现象​​:JVM暂停但无GC日志,日志显示No GCs detected。​​原因​​:JVM等待所有线程进入安全点(如…...

【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)

1.获取 authorizationCode&#xff1a; 2.利用 authorizationCode 获取 accessToken&#xff1a;文档中心 3.获取手机&#xff1a;文档中心 4.获取昵称头像&#xff1a;文档中心 首先创建 request 若要获取手机号&#xff0c;scope必填 phone&#xff0c;permissions 必填 …...

【开发技术】.Net使用FFmpeg视频特定帧上绘制内容

目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法&#xff0c;当前调用一个医疗行业的AI识别算法后返回…...

学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”

2025年#高考 将在近日拉开帷幕&#xff0c;#AI 监考一度冲上热搜。当AI深度融入高考&#xff0c;#时间同步 不再是辅助功能&#xff0c;而是决定AI监考系统成败的“生命线”。 AI亮相2025高考&#xff0c;40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕&#xff0c;江西、…...

ABAP设计模式之---“简单设计原则(Simple Design)”

“Simple Design”&#xff08;简单设计&#xff09;是软件开发中的一个重要理念&#xff0c;倡导以最简单的方式实现软件功能&#xff0c;以确保代码清晰易懂、易维护&#xff0c;并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计&#xff0c;遵循“让事情保…...

HDFS分布式存储 zookeeper

hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架&#xff0c;允许使用简单的变成模型跨计算机对大型集群进行分布式处理&#xff08;1.海量的数据存储 2.海量数据的计算&#xff09;Hadoop核心组件 hdfs&#xff08;分布式文件存储系统&#xff09;&a…...

基于TurtleBot3在Gazebo地图实现机器人远程控制

1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...

使用LangGraph和LangSmith构建多智能体人工智能系统

现在&#xff0c;通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战&#xff0c;比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...

BLEU评分:机器翻译质量评估的黄金标准

BLEU评分&#xff1a;机器翻译质量评估的黄金标准 1. 引言 在自然语言处理(NLP)领域&#xff0c;衡量一个机器翻译模型的性能至关重要。BLEU (Bilingual Evaluation Understudy) 作为一种自动化评估指标&#xff0c;自2002年由IBM的Kishore Papineni等人提出以来&#xff0c;…...