Springboot 开发 -- 集成 JWT 构建安全的API接口服务

一、JWT简介

JSON Web Token(JWT)是一种基于JSON的开放标准(RFC 7519),用于在各方之间以JSON对象的形式安全地传输信息。JWT可以被签名,确保信息在传输过程中的完整性和可信度。JWT通常用于身份验证和信息交换,特别适用于分布式系统和跨域认证场景。

官网地址:https://jwt.io/introduction/
中文网站:http://jwt.uihtm.com/

二、为什么使用JWT

相较于传统的Session认证,JWT具有以下优势:

  • 无状态和可扩展性:服务端不需要存储Session信息,易于扩展。
  • 跨域认证:JWT可以在不同的域之间传递,便于单点登录(SSO)的实现。
  • 安全性:JWT可以通过数字签名保证信息传输的安全性。
  • 自包含:JWT包含了所有用户验证所需的信息,减少了数据库查询。

三、JWT的结构

JWT由三部分组成,用.连接:

Header(头部信息):包含令牌的类型和所使用的签名算法。
Payload(有效载荷):包含所谓的Claims(声明),它们是关于实体(通常是用户)和其他数据的声明。
Signature(签名):用于验证消息在传输过程中未被篡改,并且,对于使用私钥签名的令牌,还可以验证发送者的身份。

因此,JWT 格式通常如下所示。

xxxxx.yyyyy.zzzzz

1. 头部信息

通常由两部分组成:令牌的类型,即 JWT,以及正在使用的签名算法,例如 HMAC SHA256 或 RSA。

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

然后,这个 JSON 被Base64Url编码以形成 JWT 的第一部分。

2. 有效载荷

包含声明。声明是关于实体(通常是用户)和附加数据的陈述。索赔分为三种类型:注册索赔、公开索赔和私人索赔。
一个示例有效载荷可能是::

{"sub": "1234567890","name": "John Doe","admin": true
}

然后对有效负载进行Base64Url编码以形成 JSON Web 令牌的第二部分。

3. 签名

要创建签名部分,必须获取编码的标头、编码的有效负载、秘密、标头中指定的算法,并对其进行签名。

例如,如果想使用 HMAC SHA256 算法,签名将通过以下方式创建:

HMACSHA256(base64UrlEncode(header) + "." +base64UrlEncode(payload),secret)

签名用于验证消息在此过程中没有被更改,并且在使用私钥签名的令牌的情况下,它还可以验证 JWT 的发送者就是它所说的那个人。

四、 验证 JWT

如果想玩 JWT 并将这些概念付诸实践,可以使用 jwt.io Debugger 来解码、验证和生成 JWT。
在这里插入图片描述

五、JWT 交互流程

  • 用户使用用户名密码来请求服务器
  • 服务器进行验证用户的信息
  • 服务器通过验证发送给用户一个token
  • 客户端存储token,并在每次请求时附送上这个token值
  • 服务端验证token值,并返回数据
    在这里插入图片描述

六、SpringBoot集成JWT

1. 添加依赖

在SpringBoot项目的pom.xml中添加JWT的依赖,例如使用java-jwt库:

<dependency><groupId>com.auth0</groupId><artifactId>java-jwt</artifactId><version>3.18.2</version> <!-- 请使用最新版本 -->
</dependency>

2. 创建JWT工具类

创建一个工具类来生成和验证JWT:

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;import java.util.Date;
import java.util.HashMap;
import java.util.Map;public class JwtTokenUtil {private String secret = "secretKey"; // 密钥public String generateToken(String username) {Date now = new Date();Date expiryDate = new Date(now.getTime() + 1000 * 60 * 60); // 1小时后过期Map<String, Object> claims = new HashMap<>();claims.put("username", username);return JWT.create().withIssuer("yourIssuer") // 发行人.withIssuedAt(now).withExpiresAt(expiryDate).withClaim("username", username).sign(Algorithm.HMAC256(secret));}public String getUsername(String token) {DecodedJWT jwt = JWT.require(Algorithm.HMAC256(secret)).build().verify(token);return jwt.getClaim("username").asString();}// 验证Tokenpublic boolean validateToken(String token, String username) {try {DecodedJWT jwt = JWT.require(Algorithm.HMAC256(secret)).withClaim("username", username).build().verify(token);return true;} catch (Exception e) {return false;}}
}

3. 创建认证过滤器

创建一个过滤器来拦截请求,并验证JWT的有效性:

import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {private final JwtTokenUtil jwtTokenUtil;public JwtAuthenticationFilter(JwtTokenUtil jwtTokenUtil) {this.jwtTokenUtil = jwtTokenUtil;}@Overrideprotected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)throws ServletException, IOException {final String authorizationHeader = request.getHeader("Authorization");String token = null;if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) {token = authorizationHeader.substring(7);}String username = null;boolean isTokenValid = false;if (token != null) {username = jwtTokenUtil.getUsername(token);isTokenValid = jwtTokenUtil.validateToken(token, username);}if (!isTokenValid) {response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);return;}filterChain.doFilter(request, response);}
}

4. 创建用户登录接口

创建一个用户登录接口,用于生成JWT:

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;import java.util.HashMap;
import java.util.Map;@RestController
public class AuthenticationController {private final JwtTokenUtil jwtTokenUtil;public AuthenticationController(JwtTokenUtil jwtTokenUtil) {this.jwtTokenUtil = jwtTokenUtil;}@PostMapping("/login")public Map<String, String> login(@RequestBody LoginRequest loginRequest) {String username = loginRequest.getUsername();// 这里应该添加验证用户名和密码的逻辑// 如果验证成功String token = jwtTokenUtil.generateToken(username);Map<String, String> responseMap = new HashMap<>();responseMap.put("token", token);return responseMap;}
}

五、客户端存储和使用JWT

客户端(通常是浏览器)在收到JWT后,应将其存储在本地,如LocalStorage或SessionStorage中。在随后的请求中,客户端需要在HTTP请求头中添加JWT,以验证用户身份。

六、总结

通过上述步骤,我们成功地在SpringBoot项目中集成了JWT,实现了API接口服务的身份验证。JWT提供了一种安全、高效的方式来处理身份验证和信息交换,特别适合于微服务和分布式系统。然而,需要注意的是,JWT不适用于需要高度安全的场景,如支付系统,因为JWT一旦发出,就无法撤销,除非等到它自然过期。此外,由于JWT通常存储在客户端,因此它们容易受到跨站脚本攻击(XSS)的影响。开发者应采取适当的安全措施来保护JWT,例如使用HttpOnly的Cookie标志来存储令牌,或者使用内容安全策略(CSP)来减轻XSS攻击的风险。

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

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

相关文章

12-常用类

1. 包装类 针对八种基本数据类型封装的相应的引用类型。 有了类的特点&#xff0c;就可以调用类中的方法。&#xff08;为什么要封装&#xff09; 基本数据类型包装类booleanBooleanchar CharacterbyteByteshortShortintIntegerlongLongfloatFloatdoubleDouble 1.1 …

C# Sdcb.PaddleInference 中文分词、词性标注

C# Sdcb.PaddleInference 中文分词、词性标注 目录 效果 项目 代码 下载 参考 效果 项目 代码 using Sdcb.PaddleNLP.Lac; using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Windows.Forms; namespace C__Sdcb.Pad…

kafka-消费者组-点对点测试

文章目录 1、点对点测试1.1、获取 kafka-consumer-groups.sh 的帮助信息1.2、列出所有的 消费者组1.3、创建消费者1并指定组 my_group11.4、创建消费者2并指定组 my_group11.5、创建消费者3并指定组 my_group11.6、创建生产者发送消息到 my_topic1 主题1.6.1、发送第一条消息ro…

华为WLAN无线组网技术与解决方案

WLAN无线组网技术与解决方案 网络拓扑采用AP和AC旁挂式无线组网 配置思路&#xff1a; 1.让AP上线 1.1&#xff0c;使得AP能够获得IP地址 配置步骤&#xff1a; 1.把AC当作一个一个有管理功能的三层交换机 sys Enter system view, return user view with CtrlZ. [AC6605]vlan …

【Qt】Qt框架文件处理精要:API解析与应用实例:QFile

文章目录 前言&#xff1a;1. Qt 文件概述2. 输入输出设备类3. 文件读写类3.1. 打开open3.2. 读read / readline/ readAll3.3. 写write3.4. 关闭close 4. 读写文件示例5. 文件件和目录信息类总结&#xff1a; 前言&#xff1a; 在现代软件开发中&#xff0c;文件操作是应用程序…

如何恢复已删除/丢失或未保存的 PDF 文件?

许多用户曾因某些问题删除或丢失 PDF 文件。此外&#xff0c;一些用户在关闭应用程序时未保存 PDF 文件&#xff0c;从而丢失 PDF 文件。您可以尝试一些解决方案来恢复已删除的 PDF 文件、恢复未保存的 PDF 文件&#xff0c;以及在任何其他数据丢失情况下挽救丢失的 PDF 文件。…

优化效率,简化流程:探索工资结算系统的重要性与实施方法

在现代企业中&#xff0c;工资结算是一项重要而复杂的任务。为了更好地管理和处理员工的工资事务&#xff0c;许多企业采用工资结算系统。本文将探讨工资结算系统的重要性&#xff0c;并介绍一些实施该系统的方法。 ### 1. 概述 工资结算系统是一种自动化的软件系统&#xff0…

apexcharts数据可视化之极坐标区域图

apexcharts数据可视化之极坐标区域图 有完整配套的Python后端代码。 本教程主要会介绍如下图形绘制方式&#xff1a; 基础极坐标区域图单色极坐标区域图 基础极坐标区域图 import ApexChart from react-apexcharts;export function BasicPolar() {// 数据序列const series…

【论文阅读|cryoET】DeepETPicker:使用弱监督深度学习的快速准确cryoET三维颗粒挑选算法

题目 DeepETPicker: Fast and accurate 3D particle picking for cryo-electron tomography using weakly supervised deep learning 发表期刊&#xff1a; Nature Communications 发表时间&#xff1a;2024.02 Accepted 作者&#xff1a;Guole Liu, Tongxin Niu 中科院自动化…

2024全新升级版家政服务小程序源码 支持家政预约+上门服务+SAAS系统+可二开

随着科技的飞速发展&#xff0c;家政服务行业也迎来了数字化转型的浪潮。为了满足市场日益增长的需求&#xff0c;分享一款2024全新升级版的家政服务小程序源码。该源码不仅支持家政预约和上门服务&#xff0c;还集成了SAAS系统&#xff0c;并支持二次开发&#xff0c;为用户带…

FLUKE福禄克DSX-5000或者DSX-8000如何做外部串扰测试之实践篇

近期&#xff0c;有很多朋友问如何使用DSX5000或者DSX8000测外部串扰&#xff1f; 外部串扰测试在判定外部线缆是否对网络传输造成影响的重要一环。 直接上干货&#xff0c;测试步骤如下&#xff1a; 第一步:对主机和副机进行基准设置&#xff0c;保持同步!官方是建议每24小时…

Discourse 安装后安全配置考虑

防火墙 防火墙是肯定要装机器上的&#xff0c;并且端口只开放了 443 和 22。 22 的端口还只限制了部分 IP 段的访问&#xff0c;通常只允许给内部网络的 SSH。 Web 服务应该只走 443&#xff0c;80 端口的做好自动重定向到 443。 CloudFlare 可以用一个 CloudFlare 的负载…

网络编程基础(四)

目录 前言 二、多点通信 2.1 单播 2.2 广播 2.2.1 广播得发送端实现--》类似与UDP的客户端 2.3 组播 2.3.1 组播发送端流程--》类似于UDP的客户端流程 2.3.2 组播的接收端流程---》类似于UDP的服务器端流程 前言 多点通信 一、套接字选项得获取和设置 int getsockopt(int…

Owinps静态IP代理:跨境电商的优选解决方案

在快速发展的电子商务领域&#xff0c;尤其是跨境电商行业&#xff0c;网络的稳定性和安全性是成功经营的关键因素之一。在这背后&#xff0c;少不得一个重要的跨境电商工具——代理IP&#xff0c;而这其中&#xff0c;静态IP因其独特的稳定性和安全性&#xff0c;正逐渐成为众…

linux中使用gdb调试c++的dump文件

1 查看系统是否开启dump生成 0表示没开启 ulimit -c 但是这个只是针对当前这个连接&#xff0c;如果想要永久修改可以修改配置文件&#xff1a;vim /etc/profile&#xff0c;然后添加上面的命令ulimit - c unlimited.然后执行source /etc/profile或者重启使刚刚的配置可以…

数控六面钻选购指南:如何挑选一款高效、精准的加工利器?

在木工家具、门窗制造等行业中&#xff0c;数控六面钻凭借其高效、精准的特点&#xff0c;逐渐成为现代生产线上的必备设备。然而&#xff0c;市场上的数控六面钻品牌众多&#xff0c;性能各异&#xff0c;如何选购一款适合自己的设备呢&#xff1f;本文将为您提供一份实用的选…

【稀疏三维重建】pixelSplat:仅需两张图,重建3D Gaussian Splats

文章目录 一.摘要二、相关工作 , 背景(gs)三、基于图像的三维高斯预测3.1 双视图图像编码器&#xff08;解决尺度模糊性&#xff09;3.2 &#xff08;像素对齐的&#xff09;高斯参数预测 四、实验效果 论文&#xff1a;《pixelSplat: 3D Gaussian Splats from Image Pairs for…

动态规划之买卖股票大集合

目录 引言 1.只能进行一次买卖股票&#xff08;最多只能买一股股票&#xff09; 2.可以进行多次股票买卖&#xff0c;且没有手续费&#xff08;最多只能买一股股票&#xff09; 3.可以进行多次股票买卖&#xff0c;但是有冷冻期&#xff0c;无手续费&#xff08;最多只能买一…

常用压力、流量单位换算表

一、压力为单位面积所承受的力 压力&#xff1a;绝对压力 、表压力 、大气压力。相互关系&#xff1a;绝对压力表压力大气压力 绝对压力:当压力表示与完全真空的差。测量处的实际压力。 表压力:当表示其气体数值与该地域大气压力的差值。 大气压力&#xff1a;由大气重量所…

基于C++11实现的手写线程池

在实际的项目中&#xff0c;使用线程池是非常广泛的&#xff0c;所以最近学习了线程池的开发&#xff0c;在此做一个总结。 源码&#xff1a;https://github.com/Cheeron955/Handwriting-threadpool-based-on-C-17 项目介绍 项目分为两个部分&#xff0c;在初版的时候&#x…