springboot简单集成jwt

springboot简单集成jwt

参考:https://blog.csdn.net/gjtao1130/article/details/111658060

大佬的源码是可以运行的,我写这个文章的目的是添加一些注释来辅助理解

源码

JwtInterceptor.Java

package com.xxh.jwt1.interceptor;import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.exceptions.JWTVerificationException;import com.xxh.jwt1.annotation.LoginToken;
import com.xxh.jwt1.annotation.PassToken;
import com.xxh.jwt1.entity.User;
import com.xxh.jwt1.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;/*** @title: JwtInterceptor* @Author gjt* @Date: 2020-12-21* @Description:*/
public class JwtInterceptor implements HandlerInterceptor {@Autowiredprivate UserService userService;// 拦截器,接收请求后,在执行请求前进行检测@Overridepublic boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object object) throws Exception {System.out.println("object:"+object);System.out.println("object instanceof HandlerMethod:"+(object instanceof HandlerMethod));// 如果是请求方法(比如登录方法),那么object instanceof HandlerMethod的结果为true// 如果是请求资源(global.css),那么object instanceof HandlerMethod的结果为false,但是需要拦截器放行// 如果不是映射到方法直接通过if (!(object instanceof HandlerMethod)) {return true;}// 这一步认为object是请求方法,强转HandlerMethod handlerMethod = (HandlerMethod) object;System.out.println("handlerMethod:"+handlerMethod);// 获取method对象Method method = handlerMethod.getMethod();System.out.println("method:" + method);//检查是否有 PassToken 注释,有则跳过认证,没有就继续验证if (method.isAnnotationPresent(PassToken.class)) {// 判断方法上是否有PassToken注解,有的话就获取,没有就为nullPassToken passToken = method.getAnnotation(PassToken.class);System.out.println("method.getAnnotation:" + method.getAnnotation(PassToken.class));System.out.println("passToken.required():" + passToken.required());// 获取PassToken的required()的值,这是我们自定义的。默认为true,所以使preHandle返回true,通过验证if (passToken.required()) {return true;}}// 从 http 请求头中取出 tokenString token = httpServletRequest.getHeader("token");//检查有没有需要用户权限的注解if (method.isAnnotationPresent(LoginToken.class)) {// 判断方法上是否有 LoginToken 注解,有的话就获取,没有就为nullLoginToken loginToken = method.getAnnotation(LoginToken.class);// 获取LoginToken的required()的值,这是我们自定义的。默认为trueif (loginToken.required()) {// 执行认证// token 已经在上面获取,如果没有就直接返回异常if (token == null) {throw new RuntimeException("无token,请重新登录");}// 获取 token 中的 user idString userId;try {userId = JWT.decode(token).getAudience().get(0);System.out.println("JWT.decode(token).getAudience():"+JWT.decode(token).getAudience());System.out.println("userId:"+userId);} catch (JWTDecodeException j) {throw new RuntimeException("401");}User user = userService.getUser(userId);if (user == null) {throw new RuntimeException("用户不存在,请重新登录");}// 验证 tokenJWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(user.getPassWord())).build();System.out.println("jwtVerifier:"+jwtVerifier);System.out.println("jwtVerifier.verify(token):"+jwtVerifier.verify(token));try {jwtVerifier.verify(token);} catch (JWTVerificationException e) {throw new RuntimeException("401");}return true;}}// 如果没有 PassToken 或 LoginToken 的接口,如登录获取token方法,就会直接通过return true;}@Overridepublic void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {System.out.println("hello welcome");}@Overridepublic void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {}
}

我觉得集成jwt最难的就是理解JwtInterceptor的原理了。

JwtInterceptor实现HandlerInterceptor的preHandle方法,目的是为了springboot接收到请求前,先不执行controller的方法,由拦截器的逻辑来判断该条请求是否需要拦截。

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

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

相关文章

Redis安装和使用(基于windows)

Redis是一个使用C语言编写的开源、高性能、非关系型的键值对存储数据库。它支持多种数据结构,包括字符串、列表、集合、有序集合、哈希表等。Redis的内存操作能力极强,其读写性能非常优秀,且支持持久化,可以将数据存储到磁盘上&am…

使用 React 和 ECharts 创建地球模拟扩散和飞线效果

在本博客中,我们将学习如何使用 React 和 ECharts 创建一个酷炫的地球模拟扩散效果。我们将使用 ECharts 作为可视化库,以及 React 来构建我们的应用。地球贴图在文章的结尾。 最终效果 准备工作 首先,确保你已经安装了 React,并…

大语言模型有那些能力和应用

目录 能力 应用 能力 理解语义的能力:LLM 具有强大的语义理解能力,能够理解大部分文本,包括不同语言(人类语言或计算机语言)和表达水平的文本,即使是多语言混杂、语法用词错误,也在多数情况下…

关于Java中list三个实现类区别

1. 前言: List实现Collection接口,它的数据结构是有序可以重复的结合,该结合的体系有索引;它有三个实现类:ArrayList、LinkList、Vector三个实现类。 2. 三个实现类的基本区别: 2.1 ArrayList: 底层数据…

基于python实现人脸识别登录系统

一、图片管理系统亮点:本系统注重登录方式 1.1 登录方式一: 运用本地摄像头进行实时拍照登录,拍照得到的图片识别获取人脸与文件库里的人脸进行对比登录。 1.2 登录方式二: 登录者上传图片给系统,然后系统识别图片中的…

智能安全芯片ACH512芯片描述及功能

ACH512 芯片是一款基于安全算法的高性能 SOC 芯片, 主要应用于 eMMC/SD/Nandflash 大容量存储设备、加密 U 盘、指纹识别等市场。 芯片采用 32 位内核,片内集成多种安全密码模块,包括SM1、 SM2、 SM3、 SM4、 SSF33 算法以及RSA/ECC、 ECDSA、…

torch 打印网络参数、结构

要打印网络结构,可以使用print或print(model)语句,其中model是定义的神经网络模型对象。这将输出整个网络的结构信息,包括每个层的名称、输入和输出尺寸以及参数量等。 要打印网络参数,可以使用以下代码: for name, …

io.lettuce.core.RedisCommandExecutionException: ERR EXEC without MULTI

在使用redisTemplate的事务功能时,代码运行抛出异常: io.lettuce.core.RedisCommandExecutionException: ERR EXEC without MULTIat io.lettuce.core.internal.ExceptionFactory.createExecutionException(ExceptionFactory.java:147)at io.lettuce.cor…

Vue封装组件 父子组件相互传值

在Vue中,父子组件通信是非常常见的场景。以下是使用场景以及优缺点: 使用场景: 父组件需要向子组件传递数据:父组件需要将某些数据传递给子组件,以便子组件能够根据这些数据进行展示或执行某些操作。子组件需要向父组…

数据结构 | 二叉树的各种遍历

数据结构 | 二叉树的各种遍历 文章目录 数据结构 | 二叉树的各种遍历创建节点 && 创建树二叉树的前中后序遍历二叉树节点个数二叉树叶子节点个数二叉树第k层节点个数二叉树查找值为x的节点二叉树求树的高度二叉树的层序遍历判断二叉树是否是完全二叉树 我们本章来实现二…

同调群的维度 和 同调群的秩

同调群的维度是指同调群中非零元素的最小阶数。与线性代数中对向量空间的维度的理解类似。对同调群,k维同调群的维度是k。 同调群的秩是指同调群中的自由部分的维度。同调群通常包含自由部分和挠部分。同调群的秩是指同调群中自由部分的维度。对同调群,…

SQL SERVER 设置权限和隐藏其他数据库

一、创建用户名,选择默认数据库 二、分配权限 --对用户EAM分配 View_1视图 只有 只读select权限 GRANT select on View_1 to EAM --对用户分配指定表权限(读写删) GRANT SELECT , INSERT , UPDATE , DELETE ON table1 TO [用户名] --对用户分…

更改 Mac 所使用网络服务的顺序

如果以多种不同的方式(例如使用 Wi-Fi 或以太网)接入互联网或网络,你可以更改连接时电脑所尝试的网络连接顺序。 如果有多个活跃的连接,电脑会首先尝试列表顶部的连接,然后按降序尝试其他连接。 你不能更改虚拟专用网…

详解Python 迭代器介绍及作用

文章目录 迭代器:初探什么是迭代器?通过迭代器进行迭代迭代器 for 循环的工作构建自定义迭代器Python 无限迭代器Python 迭代器的好处总结关于Python技术储备一、Python所有方向的学习路线二、Python基础学习视频三、精品Python学习书籍四、Python工具包…

Linux下安装MySQL 5.6

1、下载二进制安装文件 使用wget下载MySQL 5.6.35二进制安装文件并存放在/root目录下。 wget https://downloads.mysql.com/archives/get/p/23/file/mysql-5.6.35-linux-glibc2.5-x86_64.tar.gz ll mysql-5.6.35-linux-glibc2.5-x86_64.tar.gz 2、创建mysql用户 先创建mysql…

【c语言指针详解】复杂数据结构的指针用法

目录 一、动态内存分配 1.1 使用malloc和free函数进行内存的动态分配和释放 1.2 内存泄漏和野指针的概念和解决方法 二、复杂数据结构的指针用法 2.1 结构体指针和成员访问操作符 2.2 指针数组和指向指针的指针 2.2.1 指针数组 2.2.2 指向指针的指针 2.3 动态内存分配与结构体指…

Vue项目解决van-calendar 打开下拉框显示空白(白色),需滑动一下屏幕,才可正常显示

问题描述,如图 ipad(平板)或者 H5移动端引入Vant组件的日历组件(van-calendar),初始化显示空白,需滚动一下屏幕,才可正常显示 解决方法 需在van-calendar上绑定open"openCalendar"事件…

基于chatGPT全程辅助的Python教程(逆向教学设计)——使用pyqt5开发

安装 https://zhuanlan.zhihu.com/p/162866700 一些资源推荐 当成手册,现用现场查。 【2024版 PyQt6 Python桌面开发 视频教程(无废话版) 玩命更新中~】 这个优点是用的pycharm ,符合自己习惯 这个控件比较全,可以直接查【PyQt5从入门到…

应用层自定义协议

文章目录 一、前言二、应用层自定义协议三、通用协议格式3.1 xml3.2 josn3.3 protobuffer 后端开发必须掌握的知识点! 一、前言 应用层主要是干嘛的呢?? 应用层协议定义了应用程序之间通信的规则和标准。定义了数据的格式、数据交换的标准和…

第74讲:MySQL数据库InnoDB存储引擎事务:Redo Log与Undo Logo的核心概念

文章目录 1.InnoDB引擎中的逻辑存储结构2.事务的基本概念3.Redo log的核心概念3.1.什么是Redo log3.2.如果没有redo log面临的问题3.3.使用redo log之后是怎样的流程 4.Undo log的核心概念 1.InnoDB引擎中的逻辑存储结构 InnoDB存储引擎的逻辑结构分为以下几层: Ta…