当前位置: 首页 > 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…...

Linux系统驱动(二)字符设备驱动

文章目录 一、概念&#xff08;一&#xff09;相关概念&#xff08;二&#xff09;字符设备框架结构&#xff08;三&#xff09;用户空间和内核空间数据传输1. 函数的参数对应关系 &#xff08;四&#xff09;字符设备相关的API1. 字符设备驱动&#xff08;1&#xff09;注册字…...

Day29 | 动态规划 509. 斐波那契数 70. 爬楼梯 746. 使用最小花费爬楼梯

语言 Java 509. 斐波那契数 斐波那契数 题目 斐波那契数 &#xff08;通常用 F(n) 表示&#xff09;形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始&#xff0c;后面的每一项数字都是前面两项数字的和。也就是&#xff1a; F(0) 0&#xff0c;F(1) 1 F(n) F(n -…...

【开源移植】MultiButton_小型按键驱动模块移植

MultiButton 简介 MultiButton 是一个小巧简单易用的事件驱动型按键驱动模块&#xff0c;可无限量扩展按键&#xff0c;按键事件的回调异步处理方式可以简化你的程序结构&#xff0c;去除冗余的按键处理硬编码&#xff0c;让你的按键业务逻辑更清晰。 使用方法 1.先申请一个…...

【Python系列】Python 字典合并

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...

C# 设计模式之装饰器模式

总目录 前言 装饰器模式的主要作用就是扩展一个类的功能&#xff0c;或给一个类添加多个变化的情况。学习面向对象的都知道&#xff0c;如果想单纯的给某个类增加一些功能&#xff0c;可以直接继承该类生成一个子类就可以。应对一些简单的业务场景继承也就够了&#xff0c;但是…...

【uniapp离线打包】(基于Android studio)

文章目录 uniapp打包官方教程入口一、准备工作(工具三大件)Android Studio版本推荐 二、准备工作&#xff08;Android壳和uniapp包&#xff09;导入Android壳生成uniapp包将uniapp包导入android壳降低jdk版本 三、准备工作&#xff08;证书&#xff09;准备Android平台离线签名…...

稳稳的年化10%,多任务时序动量策略——基于pytorch的深度学习策略(附python代码)

原创文章第608篇&#xff0c;专注“AI量化投资、世界运行的规律、个人成长与财富自由"。 做因子挖掘这段时间&#xff0c;有一个观感。 传统的因子挖掘&#xff0c;尤其是手工构造因子&#xff0c;到遗传算法因子挖掘。——本身也是一种”拟合“&#xff0c;或者说试图”…...

C++分析AVL树

目录 AVL树介绍 AVL树平衡因子更新分析 AVL树插入时旋转与平衡因子更新 左单旋 右单旋 左右单旋 右左单旋 AVL旋转可行性 AVL树节点删除&#xff08;待补充&#xff09; AVL树分析 AVL树介绍 二叉搜索树在某些极端情况下可能会退化&#xff0c;为了解决这个问题&…...

aurora8b10b ip的使用(framing接口下的数据回环测试)

文章目录 一、Aurora8B/10B协议二、时钟、复位与状态指示1、时钟2、复位3、状态指示 三、数据发送、接受接口&#xff08;1&#xff09;AXI4-Stream位排序&#xff08;2&#xff09;Streaming接口&#xff08;3&#xff09;Framing接口&#xff08;帧传输接口&#xff09; 四、…...

如何通过OpenCV判断图片是否包含在视频内?

要判断图片是否包含在视频内&#xff0c;可以使用计算机视觉技术和图像处理方法。这通常涉及特征匹配或模板匹配。以下是一个基于OpenCV的解决方案&#xff0c;通过特征匹配的方法来实现这一目标。 步骤概述 读取视频和图片&#xff1a; 使用OpenCV读取视频文件和图片文件。 …...

vip影视建设网站官网/爱站数据

Objective-C中有几种数据类型和C不太一样。特此记录。 - id 是一个指针类型&#xff0c;可以指向任何类型的对象 - BOOL和char是一样的&#xff0c;但是做为布尔值使用。 YES 表示1 NO 表示0 - IBOutlet 是个没有任何意义的宏&#xff0c;可以忽略。当Interface Builder从.h…...

新手从零基础建站初级网站建设/网站建设主要推广方式

MapReduce 如何解决负载均衡和数据倾斜&#xff1a;阶段主要出在Map作业结束后&#xff0c;shuffer&#xff08;洗牌&#xff09;过程中&#xff0c;如何将map处理后的结果分成多少份&#xff0c;交由Reduce作业&#xff0c;使得每部分reduce作业尽可能均衡处理数据计算。系统默…...

wordPress主题模板站/模板免费网站建设

Struts2框架 通过配置 result标签来 把Action的处理结果和视图对应&#xff0c;来决定Action返回到哪一个视图 1.Action的处理结果是一个字符串&#xff0c;Action把这个处理结果交给Struts2框架 2.Struts2框架决定这个处理结果对应哪个视图。 <struts><package na…...

成都兴光华城市建设公司网站/网络推广工作内容怎么写

一面是技术面&#xff0c;问的问题有&#xff1a; 1、nginx熟悉吗&#xff1f;做过什么&#xff1f; 自己测试的时候需要HLS格式的流&#xff0c;所以使用&#xff1a;NginxNginx扩展模块OBS&#xff0c;将电脑屏幕采集推流到网络中做测试&#xff0c;但是由于HLS分片的原因&am…...

网站by wordpress/长沙网站优化推广方案

线图是由折线构成的图形&#xff0c;线图是把散点从左向右用直线连接起来而构成的图形&#xff0c;在以时间序列为x轴的线图中&#xff0c;可以看到数据增长的趋势。 geom_line(mapping NULL, data NULL, stat "identity",position "identity", na.rm …...

做微商进哪个网站安全吗/网络服务合同纠纷

--使用说明-- HDocsN 是要修改的数据库的名称--HDocsN_Log是要清除的日志文件的名称--修改所见的所有HDocsN 为要清除的数据库名称--修改HDocsN_Log 为所有清除的数据库的日志文件名称-- 此名称是本地数据库所在位置的响应数据库xxx_log文件USE[master]GOALTER DATABASE HDocsN…...