在Spring boot中 使用JWT和过滤器实现登录认证
在Spring boot中 使用JWT和过滤器实现登录认证
一、登录获得JWT
- 在navicat中运行如下sql,准备一张user表
-- ----------------------------
-- Table structure for t_user
-- ----------------------------
DROP TABLE IF EXISTS `t_user`;
CREATE TABLE `t_user` (`id` int(11) NOT NULL,`username` varchar(50) NOT NULL,`password` varchar(32) DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;-- ----------------------------
-- Records of t_user
-- ----------------------------
INSERT INTO `t_user` VALUES ('1', 'root', '123', '1');
- 导入pom.xml坐标
<!-- JWT依赖坐标--><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.1</version></dependency><!-- 解析JSON--><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-core</artifactId><version>2.15.2</version></dependency>
- 在工utils包下创建一个用于生成和解析JWT 令牌的工具类
public class JwtUtils {private static String signKey = "baisepengyuyan";//签名密钥(这个可以自定义)private static Long expire = 86400000L; //有效时间 1 天 = 24 小时 * 60 分钟 * 60 秒 * 1000 毫秒 = 86,400,000 milliseconds/*生成JWT令牌*/public static String generateJwt(Map<String, Object> claims){String jwt = Jwts.builder().addClaims(claims)//自定义信息(有效载荷).signWith(SignatureAlgorithm.HS256, signKey)//签名算法(头部).setExpiration(new Date(System.currentTimeMillis() + expire))//过期时间.compact();return jwt;}/*解析JWT令牌 */public static Claims parseJWT(String jwt){Claims claims = Jwts.parser().setSigningKey(signKey)//指定签名密钥.parseClaimsJws(jwt)//指定令牌Token.getBody();return claims; //返回令牌中 payload 中存储的内容(登录用户的信息)}
}
- 在pojo包下创建user类
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {private int id;private String name;private String username;private String password;
}
- 在mapper包下添加 UserMapper接口
@Mapper
public interface UserMapper {@Select("select id ,username ,password from t_user where username = #{username} and password= #{password}")User getLoginUser(User user);
}
- 在service包下添加 UserService类
@Service
public class UserService {@AutowiredUserMapper userMapper;public User login(User user) {User loginUser = userMapper.getLoginUser(user);if (loginUser == null )return null;return user;}
}
- 在utils包下添加统一响应结果封装类
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Result {private Integer code ;//1 成功 , 0 失败private String msg; //提示信息private Object data; //数据 datapublic static Result success(Object data){return new Result(1, "success", data);}public static Result success(){return new Result(1, "success", null);}public static Result error(String msg){return new Result(0, msg, null);}@Overridepublic String toString() {return "Result{" +"code=" + code +", msg='" + msg + '\'' +", data=" + data +'}';}
}
- 在controller包下添加LoginController类
@RestController
@Slf4j
public class LoginController {//依赖业务层对象@Autowiredprivate UserService userService;@PostMapping("/login")public Result login(@RequestBody User user) {//调用业务层:登录功能User loginEmp = userService.login(user);//判断:登录用户是否存在if(loginEmp !=null ){//自定义信息Map<String , Object> claims = new HashMap<>();claims.put("id", loginEmp.getId());claims.put("username",loginEmp.getUsername());claims.put("name",loginEmp.getName());//使用JWT工具类,生成身份令牌String token = JwtUtils.generateJwt(claims);return Result.success(token);}return Result.error("用户名或密码错误");}
}
这样登录获取token的接口就写好了,接下来我们来用post工具来测一下这个登录接口
这里我使用的工具是Apifox

这样我们就拿到了 这个token (这个token的有效期是一天, 有效时间的长短可以在JWT工具类那里设置)
eyJhbGciOiJIUzI1NiJ9.eyJuYW1lIjpudWxsLCJpZCI6MCwidXNlcm5hbWUiOiJtYWkiLCJleHAiOjE2OTg2NTg1OTh9.aFDGnKvMOjgpZjdgXcQfaDM1ONupOvdwYtYNxPAaN6s
这样我们就将这个登录获取JWT的功能开发好了,但是, 现在我们仍然可以访问别的请求路径,不被拦截,所以我们要引入过滤器.
二、引入过滤器
引入过滤器的就是为了,限制为未登录的用户。不让他们访问除了登录以外的资源。
那现在我们写一个测试用例,用于测试, 看看没引入过滤器和引入过滤器的区别
- 在LoginController类下添加这个方法
@GetMapping("/getResource")public Result getUser(){return Result.success("成功访问/getResource");}
添加完这个方法后 我们尝试访问 http://localhost:8080/getResource

这是我们可以看到用户在未登录的情况下, 仍然可以正常访问我们的资源, 这是我们不希望看到的.
那么我们开始引入过滤器
- 在启动类上添加 @ServletComponentScan注解
@ServletComponentScan
- 创建一个filter包 ,在这个包下创建 LoginCheckFilter类
@Slf4j
@WebFilter(urlPatterns = "/*") //拦截所有请求
public class LoginCheckFilter implements Filter {@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {//前置:强制转换为http协议的请求对象、响应对象 (转换原因:要使用子类中特有方法)HttpServletRequest request = (HttpServletRequest) servletRequest;HttpServletResponse response = (HttpServletResponse) servletResponse;//创建json解析对象ObjectMapper objectMapper = new ObjectMapper();//1.获取请求urlString url = request.getRequestURL().toString();log.info("请求路径:{}", url); //请求路径:http://localhost:8080/login//2.判断请求url中是否包含login,如果包含,说明是登录操作,放行if(url.contains("/login")){chain.doFilter(request, response);//放行请求return;//结束当前方法的执行}//3.获取请求头中的令牌(token)String token = request.getHeader("Authorization");log.info("从请求头中获取的令牌:{}",token);//4.判断令牌是否存在,如果不存在,返回错误结果(未登录)if(!StringUtils.hasLength(token)){log.info("Token不存在");Result responseResult = Result.error("NOT_LOGIN");//把Result对象转换为JSON格式字符串String json = objectMapper.writeValueAsString(responseResult);response.setContentType("application/json;charset=utf-8");//响应response.getWriter().write(json);return;}//5.解析token,如果解析失败,返回错误结果(未登录)try {if (token.startsWith("Bearer ")) {token = token.substring(7);log.info("切除Bearer 令牌:{}",token);}JwtUtils.parseJWT(token);}catch (Exception e){log.info("令牌解析失败!");Result responseResult = Result.error("NOT_LOGIN");//把Result对象转换为JSON格式字符串 (fastjson是阿里巴巴提供的用于实现对象和json的转换工具类)String json = objectMapper.writeValueAsString(responseResult);response.setContentType("application/json;charset=utf-8");//响应response.getWriter().write(json);return;}//6.放行chain.doFilter(request, response);}
}
阅读代码我们可以发现, 我们拦截了所有请求,唯独给登录请求放行
现在我们再来尝试访问

但是新的问题来了 , 我们要怎么访问这个资源呢? 对, 使用刚刚我们登录后返回的JWT令牌
我们在每次请求时都在HTTP的请求头中携带JWT令牌过去
访问 http://localhost:8080/login 获得令牌

拿到令牌后 我们访问http://localhost:8080/getResource
在请求中 添加Authorization请求头 值为 Bearer + 空格 + JWT

我们可以看到 在实际的请求总 我们多谢了一个请求头 请求头和请求参数是不一样的!!!

到此 我们已经完成了一个Spring Boot整合JWT和过滤器 完成登录验证的功能了.
相关文章:
在Spring boot中 使用JWT和过滤器实现登录认证
在Spring boot中 使用JWT和过滤器实现登录认证 一、登录获得JWT 在navicat中运行如下sql,准备一张user表 -- ---------------------------- -- Table structure for t_user -- ---------------------------- DROP TABLE IF EXISTS t_user; CREATE TABLE t_user (id int(11) …...
天堂2如何对版本里面的内容进行修改
天堂2写装备属性的问题 早一点的版本属性都是写在armor文件夹 xml档里,不再写armor里了 armor文件夹里只有防御 HP MP增加量,套装的属性都用一个技能形式写在 skills里了 在配合数据库里一个叫armorsets实现套装属性,拿皇家套做说明。 id 43…...
代码随想录Day33 LeetCode T62不同路径 LeetCode T63 不同路径II
前言 动规五部曲 1.确定dp数组含义 2.确定递推公式 3.初始化数组 4.确定遍历方式 5.打印dp数组查看分析问题 LeetCode T62 不同路径 题目链接:62. 不同路径 - 力扣(LeetCode) 题目思路: 注:n行m列而不是m行n列 1.确定dp数组含义 代表到达此下标有多少条…...
【计算机网络】分层模型和应用协议
网络分层模型和应用协议 1. 分层模型 1.1 五层网络模型 网络要解决的问题是:两个程序之间如何交换数据。 四层?五层?七层? 2. 应用层协议 2.1 URL URL(uniform resource locator,统一资源定位符&#…...
Python框架之Flask入门和视图
一、Flask入门和视图 需要安装Pycharm专业版 1. Flask简介 Python后端的2个主流框架 Flask 轻量级框架Django 重型框架 Flask是一个基于Python实现的web开发微框架 官方文档:https://flask.palletsprojects.com/ 中文文档:https://dormousehole.readthe…...
streamWriter.WriteLine
streamWriter.WriteLine写入文件有回车行 using (System.IO.StreamWriter streamWriter new System.IO.StreamWriter("D:\123.txt", false, System.Text.Encoding.Default)) { streamWriter.Write(str.Replace("…...
一键添加色彩变幻效果,视频剪辑从未如此简单!
在视频制作过程中,给视频添加特效是必不可少的环节。而其中,色彩变幻效果作为一种常用的特效,能够为视频增添独特的氛围和视觉冲击力。然而,对于许多初学者来说,如何批量给视频添加色彩变幻效果特效功能却是一个难题。…...
Linux的简介和环境搭建
简介 Linux是一套免费使用和自由传播的类Unix操作系统,是一个基于POSIX和Unix的多用户、多任务、支持多线程和多CPU的操作系统。它能运行主要的Unix工具软件、应用程序和网络协议。它支持32位和64位硬件。Linux继承了Unix以网络为核心的设计思想,是一个…...
你看现在的程序员,是怎么解bug的
大家好,我是伍六七。 干程序员的都会碰到各种各样的 bug,有的 bug 我们看一眼、或者多看几眼就能看出来问题。 但是,也有很多问题,我们看不出来,这个时候,我们不妨把我们的代码扔给 GPT,看看它…...
CSS3背景样式
在CSS 2.1中,background属性的功能还无法满足设计的需求,为了方便设计师更灵活地设计需要的网页效果,CSS3在原有background基础上新增了一些功能属性,可以在同一个对象内叠加多个背景图像,可以改变背景图像的大小尺寸&…...
JAVA同城服务同城圈子真人躲猫猫系统的玩法流程
在现在科技的发展和互联网的普及,线上社交游戏在人们的生活中占据了越来越重要的地位。JAVA同城服务同城圈子真人躲猫猫系统就是一种结合了线上社交和线下实体位置服务的全新游戏模式。在这个游戏中,玩家们可以在同一城市中寻找隐藏的对手,体…...
C++继承——圆形和圆柱体
C继承 Circular圆形类 /*圆形类*/ class Circular { private:const static double PI;double R 0; public:Circular() default;Circular(double r);double GetArea(); /*圆面积*/double GetGirth(); /*圆周长*/ }; const double Circular::PI 3.14;Circular::Circula…...
致远OA wpsAssistServlet任意文件上传漏洞复现 [附POC]
文章目录 致远OA wpsAssistServlet任意文件上传漏洞复现 [附POC]0x01 前言0x02 漏洞描述0x03 影响版本0x04 漏洞环境0x05 漏洞复现1.访问漏洞环境2.构造POC3.复现 0x06 修复建议 致远OA wpsAssistServlet任意文件上传漏洞复现 [附POC] 0x01 前言 免责声明:请勿利用…...
Java规则引擎2.1.8版本新增功能说明
规则引擎更新功能 新增: 1.决策结束节点新增结果导出excel功能; 在决策流程的结束节点,可以将决策结果导出为Excel文件。这个功能为用户提供了更多的灵活性和便利性,使他们能够轻松地将决策结果数据进行进一步的分析和处理。 2.新增公有变…...
系列四十、请谈一下Spring中事务的传播行为
一、概述 事务的传播行为指的是当一个事务方法被另一个事务方法调用时,这个事务方法应该如何进行。事务的传播行为至少发生在两个事务方法的嵌套调用中才会出现。 二、传播行为分类...
kubectl详解
陈述式资源管理方法: 1.kubernetes 集群管理集群资源的唯一入口是通过相应的方法调用 apiserver 的接口 2.kubectl 是官方的CLI命令行工具,用于与 apiserver 进行通信,将用户在命令行输入的命令,组织并转化为 apiserver 能识别的信…...
QT通过url下载http地址下的文件(文件夹)
前言 之前只写过通过http协议通信,没有写过下载http地址中的文件或者文件夹,了解一下在QT下如何下载。 其实很简单,同使用协议通信相同的是,创建QNetworkAccessManager和QNetworkRequest,设置QNetworkRequest的url&a…...
测试实施运维必备知识点
Linux常用命令 ip addr 查看ip地址信息 ping 测试物理机是否联网 dhclient 让CentOS 7自动获取一个IP地址 vim 编辑纯文本文件 who 查看是否还有其他人在登录 find 在文件系统中搜索某文件 -name filename: 表示直接查找该文件名的文件 -type filetype:…...
RTSP/Onvif安防视频平台EasyNVR接入EasyNVS,出现Login error报错的解决方法
安防视频监控汇聚EasyNVR平台,是基于RTSP/Onvif协议的安防视频平台,可支持将接入的视频流进行全平台、全终端分发,分发的视频流包括RTSP、RTMP、HTTP-FLV、WS-FLV、HLS、WebRTC等格式。为了满足用户的集成与二次开发需求,我们也提…...
在Linux环境下远程访问MeterSphere开源测试平台
文章目录 前言1. 安装MeterSphere2. 本地访问MeterSphere3. 安装 cpolar内网穿透软件4. 配置MeterSphere公网访问地址5. 公网远程访问MeterSphere6. 固定MeterSphere公网地址 前言 MeterSphere 是一站式开源持续测试平台, 涵盖测试跟踪、接口测试、UI 测试和性能测试等功能&am…...
测试微信模版消息推送
进入“开发接口管理”--“公众平台测试账号”,无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息: 关注测试号:扫二维码关注测试号。 发送模版消息: import requests da…...
基于当前项目通过npm包形式暴露公共组件
1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹,并新增内容 3.创建package文件夹...
微服务商城-商品微服务
数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...
C# 类和继承(抽象类)
抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...
如何在网页里填写 PDF 表格?
有时候,你可能希望用户能在你的网站上填写 PDF 表单。然而,这件事并不简单,因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件,但原生并不支持编辑或填写它们。更糟的是,如果你想收集表单数据ÿ…...
保姆级教程:在无网络无显卡的Windows电脑的vscode本地部署deepseek
文章目录 1 前言2 部署流程2.1 准备工作2.2 Ollama2.2.1 使用有网络的电脑下载Ollama2.2.2 安装Ollama(有网络的电脑)2.2.3 安装Ollama(无网络的电脑)2.2.4 安装验证2.2.5 修改大模型安装位置2.2.6 下载Deepseek模型 2.3 将deepse…...
Linux 内存管理实战精讲:核心原理与面试常考点全解析
Linux 内存管理实战精讲:核心原理与面试常考点全解析 Linux 内核内存管理是系统设计中最复杂但也最核心的模块之一。它不仅支撑着虚拟内存机制、物理内存分配、进程隔离与资源复用,还直接决定系统运行的性能与稳定性。无论你是嵌入式开发者、内核调试工…...
「全栈技术解析」推客小程序系统开发:从架构设计到裂变增长的完整解决方案
在移动互联网营销竞争白热化的当下,推客小程序系统凭借其裂变传播、精准营销等特性,成为企业抢占市场的利器。本文将深度解析推客小程序系统开发的核心技术与实现路径,助力开发者打造具有市场竞争力的营销工具。 一、系统核心功能架构&…...
Xcode 16 集成 cocoapods 报错
基于 Xcode 16 新建工程项目,集成 cocoapods 执行 pod init 报错 ### Error RuntimeError - PBXGroup attempted to initialize an object with unknown ISA PBXFileSystemSynchronizedRootGroup from attributes: {"isa">"PBXFileSystemSynchro…...
python数据结构和算法(1)
数据结构和算法简介 数据结构:存储和组织数据的方式,决定了数据的存储方式和访问方式。 算法:解决问题的思维、步骤和方法。 程序 数据结构 算法 算法 算法的独立性 算法是独立存在的一种解决问题的方法和思想,对于算法而言&a…...
