【spring】集成JWT实现登录验证

ops/2025/1/26 11:59:17/

在 Spring 应用中,使用 JSON Web Token (JWT) 是一种常见的认证和授权机制。JWT 是一种基于 JSON 的开放标准 (RFC 7519),用来在各方之间传递安全、可信的数据。以下是如何在 Spring 框架中集成和使用 JWT 的完整指南。


核心概念

  1. JWT 结构

    • Header:包含类型和签名算法信息。
    • Payload:包含声明 (claims),如用户信息、角色等。
    • Signature:用来验证 token 的完整性,通常使用 HMAC 或 RSA 等算法。
  2. 使用场景

    • 用户登录后,服务端生成 JWT 并返回给客户端。
    • 客户端将 JWT 存储在本地(如浏览器的 LocalStorage 或 HttpOnly Cookie 中)。
    • 客户端每次请求时,将 JWT 添加到请求头中,服务端验证后授权访问。

JWT 的使用通常分为以下几个步骤:

  1. 用户通过用户名和密码登录,后端验证用户身份。
  2. 后端生成 JWT(包含用户的相关信息),并将其返回给前端。
  3. 前端存储该 JWT(一般存储在 LocalStorage 或 Cookie 中)。
  4. 后续每次请求,前端都会将该 JWT 放入请求头的 Authorization 字段中,后端验证 JWT 的合法性。
  5. 后端根据 JWT 中的内容进行相应的认证和授权。

集成步骤

以下是 Spring Boot 项目中使用 JWT 的主要步骤:

1. 添加依赖

pom.xml 中添加 JWT 相关依赖:

<dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-api</artifactId><version>0.11.5</version>
</dependency>
<dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-impl</artifactId><version>0.11.5</version>
</dependency>
<dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-jackson</artifactId><version>0.11.5</version>
</dependency>
1. 创建 JWT 工具类

首先,创建一个 JWT 工具类用于生成和验证 JWT

java">import io.jsonwebtoken.*;
import io.jsonwebtoken.security.Keys;
import io.jsonwebtoken.security.SignatureException;import javax.crypto.SecretKey;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;public class JwtUtil {private static final String SECRET_KEY = "your_secret_key"; // 密钥// 生成安全密钥private final static SecretKey secretKey =Keys.hmacShaKeyFor(Decoders.BASE64.decode(SECRET_KEY));// 过期时间(单位:毫秒)private static final long EXPIRATION = 3600000; // 一小时// 生成JWTpublic static String generateToken(String username, Integer id) {Map<String, Object> claims = new HashMap<>();claims.put("username", username); // 可以根据需要加入更多的自定义字段claims.put("userId", id);return Jwts.builder().setClaims(claims).setIssuedAt(new Date()).setExpiration(new Date(System.currentTimeMillis() + EXPIRATION)) // 过期时间1小时.signWith(secretKey) // 签名.compact();}// 解析JWTpublic static Claims parseToken(String token) throws JwtException {try {JwtParserBuilder jwtParserBuilder = Jwts.parserBuilder().setSigningKey(secretKey);return jwtParserBuilder.build().parseClaimsJws(token).getBody();} catch (JwtException e) {// 捕获解析异常,抛出一个自定义的异常或返回nullthrow new JwtException("Invalid token: " + e.getMessage(), e);}}// 检查JWT是否有效public static boolean isTokenExpired(String token) {try {Claims claims = parseToken(token);return claims.getExpiration().before(new Date());} catch (JwtException e) {// 解析失败,视为Token无效return true;}}// 获取用户名public static String getUsername(String token) {try {Claims claims = parseToken(token);return claims != null ? claims.get("username", String.class) : null;} catch (JwtException e) {// Token无效,返回null或可以选择抛出异常return null;}}// 获取用户idpublic static Integer getUserId(String token) {try {Claims claims = parseToken(token);return claims != null ? claims.get("userId", Integer.class) : null;} catch (JwtException e) {// Token无效,返回null或可以选择抛出异常return null;}}
}
2. 创建 JWT 拦截器

接下来,创建一个 HandlerInterceptor 实现 JWT 登录验证逻辑。这个拦截器会在每次请求时验证请求头中的 JWT 是否有效。

java">import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;public class JwtInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {String token = request.getHeader("Authorization");if (token == null || !token.startsWith("Bearer ")) {response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);response.getWriter().write("Unauthorized: No token provided");return false;}token = token.substring(7); // 去掉 "Bearer " 前缀if (JwtUtil.isTokenExpired(token)) {response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);response.getWriter().write("Unauthorized: Token expired");return false;}String username = JwtUtil.getUsername(token);if (username == null) {response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);response.getWriter().write("Unauthorized: Invalid token");return false;}// 将用户名或用户信息放入请求属性中,后续处理可以使用request.setAttribute("username", username);return true; // 继续执行请求}
}
3. 配置拦截器

WebMvcConfigurer 中注册该拦截器,使其在处理请求之前执行。

java">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 WebConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new JwtInterceptor()).addPathPatterns("/**") // 所有路径都需要拦截.excludePathPatterns("/login", "/register"); // 排除登录和注册等不需要JWT验证的路径}
}
4. 创建登录接口

最后,创建一个登录接口用于用户认证,验证成功后生成 JWT 并返回给前端。

java">import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;@RestController
public class AuthController {@PostMapping("/login")public String login(@RequestParam String username, @RequestParam String password) {// 在这里根据实际情况验证用户名和密码if ("user".equals(username) && "password".equals(password)) {// 生成 JWTString token = JwtUtil.generateToken(username);return "Bearer " + token; // 返回JWT}return "Invalid credentials"; // 登录失败}
}

总结

  1. 创建了一个 JwtUtil 工具类,用于生成、解析和验证 JWT
  2. 创建了一个 JwtInterceptor 拦截器,在每次请求时验证 JWT 的有效性。
  3. 使用 WebMvcConfigurer 配置了该拦截器,并指定哪些路径需要拦截。
  4. 创建了一个登录接口,用户登录时通过用户名和密码获取 JWT

通过这些步骤,你就可以使用 JWT 实现一个基本的登录验证功能,并且在 Spring 应用中通过拦截器进行保护,确保请求中的 JWT 合法且有效。


http://www.ppmy.cn/ops/152774.html

相关文章

循环队列(C语言)

从今天开始我会开启一个专栏leetcode每日一题&#xff0c;大家互相交流代码经验&#xff0c;也当作我每天练习的自我回顾。第一天的内容是leetcode622.设计循环队列。 一、题目详细 设计你的循环队列实现。 循环队列是一种线性数据结构&#xff0c;其操作表现基于 FIFO&#…

03垃圾回收篇(D4_彻底理解GC)

目录 一、浅析大促备战过程中出现的 fullGc&#xff0c;我们能做什么&#xff1f; 1. 什么是 JVM 的 GC? 2. 写代码的时候能做什么&#xff1f; 3. 测试能做啥 4. 知识小结 二、MinorGC、MajorGC、FullGC垃圾回收介绍 1. MinorGC &#xff08;新生代垃圾回收&#xff09…

Trimble三维激光扫描-地下公共设施维护的新途径【沪敖3D】

三维激光扫描技术生成了复杂隧道网络的高度详细的三维模型 项目背景 纽约州北部的地下通道网络已有100年历史&#xff0c;其中包含供暖系统、电线和其他公用设施&#xff0c;现在已经开始显露出老化迹象。由于安全原因&#xff0c;第三方的进入受到限制&#xff0c;在没有现成纸…

字节跳动自研HTTP开源框架Hertz简介附使用示例

字节跳动自研 HTTP 框架 Hertz Hertz 是字节跳动自研的高性能 HTTP 框架&#xff0c;专为高并发、低延迟的场景设计。它基于 Go 语言开发&#xff0c;结合了字节跳动在微服务架构中的实践经验&#xff0c;旨在提供更高效的 HTTP 服务开发体验。 1. 背景介绍 随着字节跳动业务…

python中Mako用法

Mako 是一个轻量级的 Python 模板库&#xff0c;它以其高效的代码生成和灵活的表达能力著称&#xff0c;常用于 Web 开发和静态文件生成。以下是对 Mako 的核心 API介绍。 1. 安装 Mako 首先安装 Mako&#xff1a; pip install mako2. 基本用法 Mako 的核心在于 Template 类…

github汉化

本文主要讲述了github如何汉化的方法。 目录 问题描述汉化步骤1.打开github&#xff0c;搜索github-chinese2.打开项目&#xff0c;打开README.md3.下载安装脚本管理器3.1 在README.md中往下滑动&#xff0c;找到浏览器与脚本管理器3.2 选择浏览器对应的脚本管理器3.2.1 点击去…

从零开始学习PX4源码8(board)

目录 文章目录 目录PX4--board文件夹1.board 文件夹结构1.extras2. init文件夹1. rc.bodrd_defaults 板层默认配置2. rc.bodrd_sensors配置3.nuttx-config文件夹1.include 配置1.board_dma_map.h配置2.nsh配置3.scripts配置1.scripts.ld连接脚本文件2.Kconfig配置文件4.src文件…

【大数据2025】Hadoop 万字讲解

文章目录 一、大数据通识大数据诞生背景与基本概念大数据技术定义与特征大数据生态架构概述数据存储数据计算与易用性框架分布式协调服务和任务调度组件数仓架构流处理架构 二、HDFSHDFS 原理总结一、系统架构二、存储机制三、数据写入流程四、心跳机制与集群管理 安全模式&…