Spring Boot项目中集成JWT进行身份验证

news2024/9/21 8:04:24

什么是JWT?

JWT(JSON Web Token)是一种开放标准(RFC 7519),用于在网络应用环境中安全地传递信息。它主要用于在客户端和服务器之间传递经过签名的 JSON 数据,以确保数据的完整性和真实性。

1.JWT 的结构

一个标准的 JWT 包含三个部分:
(1) 头部(Header):通常包括令牌的类型(如 "JWT")以及所使用的签名算法(如 HMAC SHA256 或 RSA)。

 {
     "alg": "HS256",
     "typ": "JWT"
   }

(2) 有效负载(Payload):包含声明(Claims),这些声明可以是关于用户的身份、权限或其他信息的内容。有效负载部分可以包含三种类型的声明:
注册声明(Registered Claims):预定义的声明,例如  sub (主题)、 exp (过期时间)等。
公共声明(Public Claims):可以自定义声明,但为了避免冲突,建议在 IANA 注册表中注册。
私有声明(Private Claims):自定义的声明,通常用于特定的应用程序或服务。

{
     "sub": "1234567890",
     "name": "John Doe",
     "iat": 1516239022
}

(3)签名(Signature):为了生成签名,必须有头部和有效负载的编码,并且使用指定的算法和密钥进行签名。例如,如果使用 HMAC SHA256 算法,则签名的生成方式如下:

 HMACSHA256(
     base64UrlEncode(header) + "." +
     base64UrlEncode(payload),
     your-256-bit-secret
   )

2.JWT 的用途

身份验证(Authentication):JWT 通常用于用户登录后的身份验证。用户登录时,服务器生成一个 JWT,并将其返回给客户端,客户端在后续请求中携带这个 JWT,以证明其身份。
信息交换(Information Exchange):JWT 也可以用于在不同系统之间安全地传递信息,因为签名可以验证消息的完整性和真实性。

3.JWT 的优点

紧凑性:JWT 可以通过 URL、POST 参数或在 HTTP 头部中传输,适合在 HTTP 中传输。
自包含:JWT 包含了所有用户验证所需的信息,无需查询数据库即可验证信息。

4.JWT 的缺点

安全性问题:如果密钥泄露,JWT 的安全性将受到威胁。由于 JWT 自包含所有信息,攻击者可能会利用这些信息进行攻击。
不可撤销:一旦 JWT 被发放,即使用户退出登录或权限更改,也不会立即撤销,直到 JWT 过期或失效。

在Spring Boot项目中集成JWT进行身份验证

在 Spring Boot 项目中集成 JWT 进行身份验证通常涉及以下几个步骤:

1. 添加依赖

首先,确保你的  pom.xml  文件中包含所需的依赖。如果你使用的是 Maven,添加以下依赖项:   

 <dependencies>
       <!-- Spring Boot Starter Web -->
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-web</artifactId>
       </dependency>

       <!-- Spring Boot Starter Security -->
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-security</artifactId>
       </dependency>

       <!-- JWT Library -->
       <dependency>
           <groupId>io.jsonwebtoken</groupId>
           <artifactId>jjwt</artifactId>
           <version>0.9.1</version>
       </dependency>
   </dependencies>

2. 创建 JWT 工具类

编写一个工具类用于生成和解析 JWT。这个类将负责创建 JWT 并验证其有效性。  

 import io.jsonwebtoken.Claims;
   import io.jsonwebtoken.Jwts;
   import io.jsonwebtoken.SignatureAlgorithm;
   import org.springframework.beans.factory.annotation.Value;
   import org.springframework.stereotype.Component;

   import java.util.Date;

   @Component
   public class JwtUtil {

       @Value("${jwt.secret}")
       private String secretKey;

       @Value("${jwt.expiration}")
       private long expiration;

       public String generateToken(String username) {
           return Jwts.builder()
                   .setSubject(username)
                   .setIssuedAt(new Date())
                   .setExpiration(new Date(System.currentTimeMillis() + expiration * 1000))
                   .signWith(SignatureAlgorithm.HS256, secretKey)
                   .compact();
       }

       public Claims extractClaims(String token) {
           return Jwts.parser()
                   .setSigningKey(secretKey)
                   .parseClaimsJws(token)
                   .getBody();
       }

       public String extractUsername(String token) {
           return extractClaims(token).getSubject();
       }

       public boolean isTokenExpired(String token) {
           return extractClaims(token).getExpiration().before(new Date());
       }

       public boolean validateToken(String token, String username) {
           return (username.equals(extractUsername(token)) && !isTokenExpired(token));
       }
   }

3. 配置 Spring Security

创建一个自定义的 JwtAuthenticationFilter  来处理 JWT 的验证和解析。  

 import org.springframework.beans.factory.annotation.Autowired;
   import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
   import org.springframework.security.core.context.SecurityContextHolder;
   import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

   import javax.servlet.FilterChain;
   import javax.servlet.ServletException;
   import javax.servlet.ServletRequest;
   import javax.servlet.ServletResponse;
   import javax.servlet.http.HttpServletRequest;
   import java.io.IOException;

   public class JwtAuthenticationFilter extends UsernamePasswordAuthenticationFilter {

       @Autowired
       private JwtUtil jwtUtil;

       @Override
       public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
               throws IOException, ServletException {
           HttpServletRequest httpServletRequest = (HttpServletRequest) request;
           String authHeader = httpServletRequest.getHeader("Authorization");

           if (authHeader != null && authHeader.startsWith("Bearer ")) {
               String token = authHeader.substring(7);
               String username = jwtUtil.extractUsername(token);

               if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
                   if (jwtUtil.validateToken(token, username)) {
                       UsernamePasswordAuthenticationToken authentication =
                               new UsernamePasswordAuthenticationToken(username, null, new ArrayList<>());
                       SecurityContextHolder.getContext().setAuthentication(authentication);
                   }
               }
           }

           chain.doFilter(request, response);
       }
   }

4. 配置 Spring Security 以使用 JWT 过滤器

 import org.springframework.beans.factory.annotation.Autowired;
   import org.springframework.context.annotation.Bean;
   import org.springframework.context.annotation.Configuration;
   import org.springframework.security.config.annotation.web.builders.HttpSecurity;
   import org.springframework.security.config.annotation.web.builders.WebSecurity;
   import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
   import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

   @Configuration
   @EnableWebSecurity
   public class SecurityConfig extends WebSecurityConfigurerAdapter {

       @Autowired
       private JwtAuthenticationFilter jwtAuthenticationFilter;

       @Override
       protected void configure(HttpSecurity http) throws Exception {
           http.csrf().disable()
               .authorizeRequests()
               .antMatchers("/public/**").permitAll()
               .anyRequest().authenticated()
               .and()
               .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
       }
   }

5. 配置 application.properties

配置 JWT 的秘密密钥和过期时间。

   jwt.secret=mySecretKey
   jwt.expiration=86400

6. 创建控制器

创建一个控制器来处理用户登录和返回 JWT 令牌。   


   import org.springframework.beans.factory.annotation.Autowired;
   import org.springframework.web.bind.annotation.PostMapping;
   import org.springframework.web.bind.annotation.RequestBody;
   import org.springframework.web.bind.annotation.RestController;

   @RestController
   public class AuthController {

       @Autowired
       private JwtUtil jwtUtil;

       @PostMapping("/login")
       public String login(@RequestBody LoginRequest loginRequest) {
           // 验证用户凭证(用户名和密码)
           // 省略实际验证逻辑

           return jwtUtil.generateToken(loginRequest.getUsername());
       }
   }

其中  LoginRequest  是一个包含  username 和  password  的请求体类。


。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。


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

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

相关文章

2024国赛数学建模C题思路模型

完整的思路模型请查看文末名片

java项目热部署

idea java项目热部署

实验三 数组和字符串的使用

实验目的及要求 目的&#xff1a; 了解多维数组的创建和使用&#xff0c;掌握一维数组和二维数组的创建和使用及String和StringBuffer类的创建方法&#xff0c;掌握String类中常用方法的使用&#xff0c;掌握String类中equals()方法和””的区别&#xff0c;区分数组的length…

learn C++ NO.12——vector

前言 不知何时开始产生了不更新博客的习惯&#xff0c;开始编程学习也过了两年多了。恍惚了一个阶段&#xff0c;我觉得是时候恢复博客产出了&#xff0c;我认为写博客是一种好的学习的方式&#xff0c;不仅可以让你对已经学习过的知识又一遍回顾&#xff0c;还记录了你编程学…

2024年全国大学生数学建模竞赛(A题) 建模解析|“板凳龙” 闹元宵|小鹿学长带队指引全代码文章与思路

我是鹿鹿学长&#xff0c;就读于上海交通大学&#xff0c;截至目前已经帮200人完成了建模与思路的构建的处理了&#xff5e; 本篇文章是鹿鹿学长经过深度思考&#xff0c;独辟蹊径&#xff0c;实现综合建模。独创复杂系统视角&#xff0c;帮助你解决国赛的难关呀。 完整内容可以…

React学习-hooks

官方文档&#xff1a;https://zh-hans.react.dev/reference/react/useActionState 1.useEffect useEffect(setup, dependencies?) 1.1 基础使用 //hooks import { useEffect } from "react"; import "./App.css";function App(){useEffect(()>{con…

kaggle注册收不到验证码、插件如何下载安装

综合这三个来看&#xff0c; 1.插件下载用的大佬给的分享链接 2.下载好压缩包以后需要解压缩 Header Editor插件网盘下载安装教程 - 哔哩哔哩 (bilibili.com) 3.安装插件时没找到crx文件&#xff0c;在浏览器插件界面点击“加载解压缩的扩展” 4.复制网址到插件里&#xff…

基于IDEA快速重构代码的几种方式

文章目录 1. 方法重构1.1 操作方式1.2 优化方式 2. 类重构2.1 操作方式2.2 优化方式 3. 基于代码分析重构3.1 操作方式 4 基于重复代码重构4.1 操作方式 本篇主要基于AI工具 TONGYI Lingma, 静态代码分析工具 Qodana 进行讨论 1. 方法重构 当你对某个封装的方法不满意时, 借助…

在js渲染的dom中的事件中传递对象

在某些情况下&#xff0c;可能需要将整个对象或部分对象嵌入到 HTML 元素的属性中&#xff0c;可以将对象数据序列化为 JSON 字符串&#xff0c;存储在 data-* 自定义属性中。这样可以在事件中取出并解析对象数据&#xff1a; <!DOCTYPE html> <html lang"en&qu…

Ubuntu Python与GitHub API 交互,获取仓库更新信息

1. 获取 GitHub 个人访问令牌 登录 GitHub &#xff0c;首先使用帐户登录 GitHub 在 GitHub 页面右上角点击头像&#xff0c;然后选择 “Settings” 在左侧菜单栏滚动到最下方&#xff0c;找到并点击 “Developer settings” 在 “Developer settings” 页面中&#xff0c…

【笔记】数据结构08

文章目录 最小堆的构建 另一个树的子树找树左下角的值 折半查找的平均查找长度[顺序表] 画出折半查找树将关键字按完全二叉树形式画出查找树 l o g 2 n 1 log_2n1 log2​n112个结点画出高度为4的查找树 1层1个节点比较1次&#xff0c;2层2个节点比较2次&#xff0c;3层4个节点…

2024年高教杯国赛(A题)碰撞检测模型+最优螺距|数学建模竞赛解题思路|完整代码论文集合

我是Tina表姐&#xff0c;毕业于中国人民大学&#xff0c;对数学建模的热爱让我在这一领域深耕多年。我的建模思路已经帮助了百余位学习者和参赛者在数学建模的道路上取得了显著的进步和成就。现在&#xff0c;我将这份宝贵的经验和知识凝练成一份全面的解题思路与代码论文集合…

计算机,数学,AI在社会模拟中的应用

国家智囊团会使用社会模拟器来预测社会动向和一些问题的涌现&#xff0c;亚洲社会仿真学会&#xff08;ASSA&#xff09;最近在武汉成立&#xff0c;旨在推动大型社会模拟器的研发和应用。 未来随着计算机算力的提升以及人工智能的进化&#xff0c;我们每个人都可能在计算机中被…

如何通过学习英语,打出人生的‘王炸’?

如何通过学习英语&#xff0c;打出人生的‘王炸’&#xff1f; 每个人都渴望一张“王炸”牌&#xff0c;能瞬间改变人生的走向。有的人通过天赋&#xff0c;有的人依靠机遇&#xff0c;而今天我们要探讨的&#xff0c;是通过学习英语打出人生“王炸”的真实故事。英语&#xf…

DB2创建数据库-创建用户-赋值权限-导入数据

这篇文章主要内容以下几点&#xff1a; 1&#xff09;创建数据库 2&#xff09;创建用户 3&#xff09;给用户赋权限 4&#xff09;导入准备好的建表语句和数据 一、创建数据库 安装DB2数据库软件&#xff0c;在我另一篇文章写有&#xff0c;自己查看。这里不讲解安装。假设你…

react 使用Ant Design中DatePicker设置mode=“year“无法获取value

一、问题描述 <DatePicker placeholder"请选择年份" mode"year" onChange{this.onChange}/>// 使用上边代码&#xff0c;界面呈现出只有年份的选择器。但是&#xff0c; onChange 事件根本不会触发&#xff0c;获取不了值&#xff01;二、解决办…

【系统架构设计师-2011年】综合知识-答案及详解

更多内容请见&#xff1a; 备考系统架构设计师-核心总结索引 文章目录 【第1题】【第2~4题】【第5~7题】【第8题】【第9题】【第10题】【第11题】【第12题】【第13题】【第14题】【第15题】【第16题】【第17题】【第18~19题】【第20~21题】【第22题】【第23题】【第24题】【第2…

【PyQt6 应用程序】解说+原声视频混剪无显卡精简版,无显卡可用

在当今视频内容创作日益繁荣的时代,利用自动化工具进行视频编辑和二次创作已成为提高生产效率和创作水平的重要手段。本文将介绍如何使用PyQt6创建一个应用程序,该程序能够自动提取视频中的解说和原声部分,并使用人工智能对解说进行二次创作,从而生成具有独特风格的新视频内…

[网络原理]关于网络的基本概念 及 协议

文章目录 一. 关于网络的概念介绍1. 局域⽹LAN2. ⼴域⽹WAN3. 主机4. 路由器5. 交换机IP地址端口号 二. 协议协议分层TCP/IP五层模型(或四层)OSI七层模型封装分用 一. 关于网络的概念介绍 1. 局域⽹LAN 局域⽹&#xff0c;即 Local Area Network&#xff0c;简称LAN。 Local …

会声会影2024是一款功能强大的专业视频制作软件及会声会影字体怎么安装

字幕在视频中扮演着多重角色&#xff0c;对于不同类型的观众都有重要意义。通过提供文字信息&#xff0c;字幕帮助观众更好地理解视频内容&#xff0c;特别是对于那些听力受损或不懂视频语言的观众来说&#xff0c;字幕是他们获取信息的重要途径。这篇文章就一起来看看会声会影…