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

Spring Boot应用中实现基于JWT的登录拦截器,以保证未登录用户无法访问指定的页面

        

目录

一、配置拦截器进行登录校验

1. 在config层设置拦截器

2. 实现LoginInterceptor拦截器

3. 创建JWT工具类

4. 在登录时创建JWT并存入Cookie

二、配置JWT依赖和环境

1. 添加JWT依赖

2. 配置JWT环境

 


本篇博客将为大家介绍了如何在Spring Boot应用中实现基于JWT的登录拦截器,以保证未登录用户无法访问指定的页面。

一、配置拦截器进行登录校验

1. 在config层设置拦截器

我们首先在config层创建一个配置类,用来设置需要拦截的页面。在Spring Boot中,我们可以通过实现WebMvcConfigurer接口来配置拦截器。

创建LoginConfig类:
import com.bim.bimbookshop.interceptor.LoginInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;/*** 登录拦截配置类*/
@Configuration   // 表明这个是配置类
public class LoginConfig implements WebMvcConfigurer {@Autowiredprivate LoginInterceptor loginInterceptor;/*** 配置拦截器* @param registry*/@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(loginInterceptor)  // 添加拦截器.addPathPatterns("/**")  // 配置拦截路径.excludePathPatterns("/login/**", "/static/**", "/templates/**"); // 配置排除路径}
}

这里的addPathPatterns("/**")表示拦截所有路径,而excludePathPatterns用于排除登录、注册等静态资源的路径。例如,/login/**表示排除所有与登录相关的请求。

2. 实现LoginInterceptor拦截器

接下来,我们需要在interceptor层创建一个拦截器类,用来判断用户是否已登录。

创建LoginInterceptor类:
import com.bim.bimbookshop.util.JwtUtil;
import io.jsonwebtoken.Claims;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;/*** 登录拦截器*/
@Component
public class LoginInterceptor implements HandlerInterceptor {/*** 过滤除登录请求外的其他请求* @param request* @param response* @param handler* @return* @throws Exception*/@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {Cookie[] cookies = request.getCookies();if (cookies != null) {for (Cookie cookie : cookies) {if ("token".equals(cookie.getName())) {String userToken = cookie.getValue();if (!StringUtils.hasText(userToken)) {response.sendError(HttpServletResponse.SC_UNAUTHORIZED); // 未认证}// 解析token并验证try {Claims claims = JwtUtil.parseJWT(userToken);claims.getSubject();  // 如果解析成功,代表用户已登录} catch (Exception e) {System.out.println("Token信息出错");return false; // 如果token无效,返回false,阻止访问}return true;  // 放行}}}return false;  // 如果没有找到token,则返回false,拒绝访问}
}

3. 创建JWT工具类

我们需要一个工具类来生成和解析JWT。这个类会提供生成JWT的功能,并在拦截器中进行解析和验证。

创建JwtUtil类:
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
import java.util.Date;
import java.util.UUID;/*** JWT工具类*/
public class JwtUtil {// 设置过期时间,单位为毫秒public static final Long JWT_TTL = 60 * 60 * 1000L; // 1小时public static final String JWT_KEY = "qcby";  // 密钥/*** 创建token* @param subject 主题,可以是用户的ID或其他信息* @return JWT token*/public static String createJWT(String subject) {SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;long nowMillis = System.currentTimeMillis();Date now = new Date(nowMillis);long expMillis = nowMillis + JWT_TTL;Date expDate = new Date(expMillis);SecretKey secretKey = generalKey();JwtBuilder builder = Jwts.builder().setId(UUID.randomUUID().toString())  // 唯一的ID.setSubject(subject)  // 主题.setIssuer("wd")  // 签发者.setIssuedAt(now)  // 签发时间.signWith(signatureAlgorithm, secretKey)  // 使用HS256算法进行加密.setExpiration(expDate);  // 设置过期时间return builder.compact();}/*** 生成加密后的秘钥* @return SecretKey*/public static SecretKey generalKey() {byte[] encodedKey = Base64.getDecoder().decode(JWT_KEY);return new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");}/*** 解析JWT* @param jwt token* @return Claims* @throws Exception*/public static Claims parseJWT(String jwt) throws Exception {SecretKey secretKey = generalKey();return Jwts.parser().setSigningKey(secretKey).parseClaimsJws(jwt).getBody();}
}

4. 在登录时创建JWT并存入Cookie

在用户登录成功后,我们会生成一个JWT,并将其保存到浏览器的Cookie中。这样,用户下次访问时,可以通过解析Cookie中的token来验证登录状态。

登录方法:
public ResponseResult Login(Login login, HttpServletResponse response) {// 登录验证逻辑// 登录成功后,根据用户ID生成JWTString token = this.jwtUtil.createJWT(String.valueOf(user.getUserId()));// 将token存入Cookie中Cookie cookie = new Cookie("token", token);cookie.setPath("/");  // 将cookie作用域设置为整个网站cookie.setMaxAge(36000);  // 设置cookie过期时间为10小时response.addCookie(cookie);  // 将cookie添加到响应中return new ResponseResult("登录成功");
}

二、配置JWT依赖和环境

1. 添加JWT依赖

为了能够使用JWT库,我们需要在pom.xml中添加依赖。

<dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.1</version>
</dependency>

2. 配置JWT环境

我们可以在application.ymlapplication.properties中配置JWT相关的参数,例如过期时间、密钥等。

spring:...
jwt:secret: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4K67DMlSPXbgG0MPp0gHexpire: 86400000  # 设置过期时间为一天(单位为毫秒)subject: door     # 设置令牌的主题

总结

通过以上步骤,我们在Spring Boot应用中实现了基于JWT的登录认证功能。我们使用拦截器对用户请求进行拦截,只有拥有有效JWT的用户才能访问受保护的资源。这样可以有效地保证系统的安全性和用户体验。

相关文章:

Spring Boot应用中实现基于JWT的登录拦截器,以保证未登录用户无法访问指定的页面

目录 一、配置拦截器进行登录校验 1. 在config层设置拦截器 2. 实现LoginInterceptor拦截器 3. 创建JWT工具类 4. 在登录时创建JWT并存入Cookie 二、配置JWT依赖和环境 1. 添加JWT依赖 2. 配置JWT环境 本篇博客将为大家介绍了如何在Spring Boot应用中实现基于JWT的登录…...

MySQL 基础学习(1):数据类型与操作数据库和数据表

MySQL 基础学习&#xff1a;数据类型与操作数据库和数据表 在这篇博客中&#xff0c;我们将深入学习 MySQL 的基础操作&#xff0c;重点关注数据库和数据表的操作&#xff0c;以及 MySQL 中常见的数据类型。希望本文能帮助你更好地理解和掌握 MySQL 的基本用法。 一、操作数据…...

zyNo.19

哈希&#xff08;md5&#xff09;绕过问题 本质上是弱类型问题的延申 题型 登录的哈希验证 $a ! $b Md5($a) md5($b) 解决办法Md5绕过 var_dump ("0e123456" "0e4456789"); //true 0e545993274517709034328855841020//true 参考资料0e开头的哈希…...

Kafka生产者ACK参数与同步复制

目录 生产者的ACK参数 ack等于0 ack等于1&#xff08;默认&#xff09; ack等于-1或all Kafka的同步复制 使用误区 生产者的ACK参数 Kafka的ack机制可以保证生产者发送的消息被broker接收成功。 Kafka producer有三种ack机制 &#xff0c;分别是 0&#xff0c;1&#xf…...

IPhone14 Pro 设备详情

目录 产品宣传图内部图——后设备详细信息 产品宣传图 内部图——后 设备详细信息 信息收集于HubWeb.cn...

【Linux】磁盘

没有被打开的文件 文件在磁盘中的存储 认识磁盘 磁盘的存储构成 磁盘的效率 与磁头运动频率有关。 磁盘的逻辑结构 把一面展开成线性。 通过扇区的下标编号可以推算出在磁盘的位置。 磁盘的寄存器 控制寄存器&#xff1a;负责告诉磁盘是读还是写。 数据寄存器&#xff1a;给…...

Shell编程(for循环+并发问题+while循环+流程控制语句+函数传参+函数变量+函数返回值+反向破解MD5)

本篇文章继续给大家介绍Shell编程&#xff0c;包括for循环、并发问题&#xff0c;while循环&#xff0c;流程控制语句&#xff0c;函数传参、函数变量、函数返回值&#xff0c;反向破解MD5等内容。 1.for循环 for 变量 in [取值列表] 取值列表可以是数字 字符串 变量 序列…...

强化学习数学原理(三)——值迭代

一、值迭代过程 上面是贝尔曼最优公式&#xff0c;之前我们说过&#xff0c;f(v)v&#xff0c;贝尔曼公式是满足contraction mapping theorem的&#xff0c;能够求解除它最优的策略和最优的state value&#xff0c;我们需要通过一个最优v*&#xff0c;这个v*来计算状态pi*&…...

Day27-【13003】短文,什么是栈?栈为何用在递归调用中?顺序栈和链式栈是什么?

文章目录 第三章栈和队列总览第一节栈概览栈的定义及其基本操作如何定义栈和栈的操作&#xff1f;合理的出栈序列个数如何计算&#xff1f;栈的两种存储方式及其实现&#xff1f;顺序栈及其实现&#xff0c;还有对应时间复杂度*、清空栈&#xff0c;初始化栈5、栈空&#xff0c…...

[JMCTF 2021]UploadHub

题目 上传.htaccess就是修改配置文件 <FilesMatch .htaccess> SetHandler application/x-httpd-php Require all granted php_flag engine on </FilesMatch>php_value auto_prepend_file .htaccess #<?php eval($_POST[md]);?>SetHandler和ForceType …...

C++学习——认识和与C的区别

目录 前言 一、什么是C 二、C关键字 三、与C语言不同的地方 3.1头文件 四、命名空间 4.1命名空间的概念写法 4.2命名空间的访问 4.3命名空间的嵌套 4.4命名空间在实际中的几种写法 五、输入输出 5.1cout 5.2endl 5.3cin 总结 前言 开启新的篇章&#xff0c;这里…...

为AI聊天工具添加一个知识系统 之63 详细设计 之4:AI操作系统 之2 智能合约

本文要点 要点 AI操作系统处理的是 疑问&#xff08;信念问题&#xff09;、缺省&#xff08;逻辑问题&#xff09;和异常(不可控因素 ) 而 内核 的三大功能 &#xff08;资源分配/进程管理/任务调度&#xff09;以及外围的三类接口&#xff08; CLI、GUI和表面模型的 运行时…...

基于SpringBoot的网上摄影工作室开发与实现 | 含论文、任务书、选题表

随着互联网技术的不断发展&#xff0c;摄影爱好者们越来越需要一个在线平台来展示和分享他们的作品。基于SpringBoot的网上摄影工作室应运而生&#xff0c;它不仅为用户提供了一个展示摄影作品的平台&#xff0c;还为管理员提供了便捷的管理工具。本文幽络源将详细介绍该系统的…...

Flutter子页面向父组件传递数据方法

在 Flutter 中&#xff0c;如果父组件需要调用子组件的方法&#xff0c;可以通过以下几种方式实现。以下是常见的几种方法&#xff1a; 方法 1&#xff1a;使用 GlobalKey 和 State 调用子组件方法 这是最直接的方式&#xff0c;通过 GlobalKey 获取子组件的 State&#xff0c…...

回顾Maven

Maven Maven简介 Maven 是 Apache 软件基金会的一个开源项目,是一个优秀的项目构建工具,它 用来帮助开发者管理项目中的 jar,以及 jar 之间的依赖关系、完成项目的编译、 测试、打包和发布等工作。 管理jar包管理jar包之间的依赖关系&#xff08;其中一个jar包可能同时依赖多个…...

除了layui.js还有什么比较好的纯JS组件WEB UI?在谷歌浏览上显示

以下是一些比较好的纯JS组件WEB UI&#xff0c;可以在谷歌浏览器上良好显示&#xff1a; 1. Sencha 特点&#xff1a;提供超过140个高性能UI组件&#xff0c;用于构建现代应用程序。支持与Angular和React集成&#xff0c;提供企业级网格解决方案。 适用场景&#xff1a;适用于…...

力扣111二叉树的最小深度(DFS)

Problem: 111. 二叉树的最小深度 文章目录 题目描述思路复杂度Code 题目描述 思路 1.欲望求出最短的路径&#xff0c;先可以记录一个变量minDepth&#xff0c;同时记录每次当前节点所在的层数currentDepth 2.在递的过程中&#xff0c;每次递一层&#xff0c;也即使当前又往下走…...

c++学习第十三天

创作过程中难免有不足&#xff0c;若您发现本文内容有误&#xff0c;恳请不吝赐教。 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 一、vector 1.介绍 1. vector是表示可变大小数组的序列容器。 2. 就像数组一样&#xff0c;vector也采用的连续存储空…...

zookeeper-3.8.3-基于ACL的访问控制

ZooKeeper基于ACL的访问控制 ZooKeeper 用ACL控制对znode的访问&#xff0c;类似UNIX文件权限&#xff0c;但无znode所有者概念&#xff0c;ACL指定ID及对应权限&#xff0c;且仅作用于特定znode&#xff0c;不递归。 ZooKeeper支持可插拔认证方案&#xff0c;ID格式为scheme…...

Java定时任务实现方案(四)——Spring Task

Spring Task 这篇笔记&#xff0c;我们要来介绍实现Java定时任务的第四个方案&#xff0c;使用Spring Task&#xff0c;以及该方案的优点和缺点。 ​ Spring Task是Spring框架提供的一个轻量级任务调度框架&#xff0c;用于简化任务调度的开放&#xff0c;通过注解或XML配置的…...

Java 8 Stream API 入门到实践详解

一、告别 for 循环&#xff01; 传统痛点&#xff1a; Java 8 之前&#xff0c;集合操作离不开冗长的 for 循环和匿名类。例如&#xff0c;过滤列表中的偶数&#xff1a; List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例

使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件&#xff0c;常用于在两个集合之间进行数据转移&#xff0c;如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model&#xff1a;绑定右侧列表的值&…...

Opencv中的addweighted函数

一.addweighted函数作用 addweighted&#xff08;&#xff09;是OpenCV库中用于图像处理的函数&#xff0c;主要功能是将两个输入图像&#xff08;尺寸和类型相同&#xff09;按照指定的权重进行加权叠加&#xff08;图像融合&#xff09;&#xff0c;并添加一个标量值&#x…...

【算法训练营Day07】字符串part1

文章目录 反转字符串反转字符串II替换数字 反转字符串 题目链接&#xff1a;344. 反转字符串 双指针法&#xff0c;两个指针的元素直接调转即可 class Solution {public void reverseString(char[] s) {int head 0;int end s.length - 1;while(head < end) {char temp …...

Java线上CPU飙高问题排查全指南

一、引言 在Java应用的线上运行环境中&#xff0c;CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时&#xff0c;通常会导致应用响应缓慢&#xff0c;甚至服务不可用&#xff0c;严重影响用户体验和业务运行。因此&#xff0c;掌握一套科学有效的CPU飙高问题排查方法&…...

JVM虚拟机:内存结构、垃圾回收、性能优化

1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...

Python Einops库:深度学习中的张量操作革命

Einops&#xff08;爱因斯坦操作库&#xff09;就像给张量操作戴上了一副"语义眼镜"——让你用人类能理解的方式告诉计算机如何操作多维数组。这个基于爱因斯坦求和约定的库&#xff0c;用类似自然语言的表达式替代了晦涩的API调用&#xff0c;彻底改变了深度学习工程…...

Oracle11g安装包

Oracle 11g安装包 适用于windows系统&#xff0c;64位 下载路径 oracle 11g 安装包...

c# 局部函数 定义、功能与示例

C# 局部函数&#xff1a;定义、功能与示例 1. 定义与功能 局部函数&#xff08;Local Function&#xff09;是嵌套在另一个方法内部的私有方法&#xff0c;仅在包含它的方法内可见。 • 作用&#xff1a;封装仅用于当前方法的逻辑&#xff0c;避免污染类作用域&#xff0c;提升…...

Python网页自动化Selenium中文文档

1. 安装 1.1. 安装 Selenium Python bindings 提供了一个简单的API&#xff0c;让你使用Selenium WebDriver来编写功能/校验测试。 通过Selenium Python的API&#xff0c;你可以非常直观的使用Selenium WebDriver的所有功能。 Selenium Python bindings 使用非常简洁方便的A…...