spring boot3x登录开发-上(整合jwt)

⛰️个人主页:     蒾酒

🔥系列专栏:《spring boot实战》

🌊山高路远,行路漫漫,终有归途。


目录

前置条件

jwt简介

导依赖

编写jwt工具类

1.配置项直接嵌入代码,通过类名.静态方法使用

2.配置项写到application.yml,交由spring容器管理依赖注入使用


前置条件

已经初始化好一个spring boot项目且版本为3X,项目可正常启动。

作者版本为3.2.2

初始化教程:

新版idea创建spring boot项目-CSDN博客文章浏览阅读2.5k次,点赞60次,收藏66次。本教程对新手小白友好。若根据教程创建出现问题导致失败可下载我提供的源码,在文章最后。本教程较新本文使用的工具以及搭建的springboot版本都是很新版本:idea版本如下spring boot 版本如下:本教程使用的是汉化后的idea。https://blog.csdn.net/qq_62262918/article/details/135785412?spm=1001.2014.3001.5501

jwt简介

  1. JWT(JSON Web Token)是一种开放标准(RFC 7519),用于在网络应用间传输和存储信息的一种安全方式。
  2. 它由三部分组成:头部(Header)、载荷(Payload)和签名(Signature)。
  3. JWT可以被用作身份验证和授权,通过在服务器和客户端之间传递令牌来验证用户的身份并允许访问受保护的资源。
  4. 由于JWT是基于数字签名的,所以可以确保数据的完整性和安全性。它的设计简单、易于实现,并且可以跨不同的平台和语言使用。

导依赖

pom.xml:

 <dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.1</version></dependency>
<!-- 如果jdk大于1.8,则还需导入下面依赖--><dependency><groupId>javax.xml.bind</groupId><artifactId>jaxb-api</artifactId><version>2.3.1</version></dependency>

注意:你的jdk版本如果为1.8导入第一个就行,大于1.8就要导入两个。

编写jwt工具类

JWT(JSON Web Token)工具类在实际开发中通常包含以下一些常用方法:

  1. 生成JWT:用于生成JWT令牌并返回令牌字符串。
  2. 解析JWT:用于解析JWT令牌,验证签名,并获取其中的声明信息。
  3. 验证JWT:用于验证JWT的有效性,包括验证签名、过期时间等。
  4. 刷新JWT:用户还在操作,马上要快过期时,延长其有效期(无感刷新)。
  5. 其他辅助方法:例如获取JWT中的特定声明信息,验证JWT是否包含某个声明,等等。

其中生成和解析token是必须的,其他方法根据项目需求设计来决定写不写。

1.配置项直接嵌入代码,通过类名.静态方法使用

jwt工具类如下:

上面五种常用方法已经写好,cv过来直接能用。按需修改也可以。

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.Map;/*** @author mijiupro*/
public class JwtUtils {private static final String SIGN_KEY = "mijiu";// 加密密钥private static final long EXPIRE_TIME = 12 * 60 * 60 * 1000; //到期时间,12小时,单位毫秒private static final byte[] SECRET_KEY = SIGN_KEY.getBytes(StandardCharsets.UTF_8);/*** 生成token令牌* @param claims JWT第二部分负载 payload 中存储的内容* @param subject 主题(用户类型)* @return token*/public static String generateToken(Map<String,Object> claims, String subject) {return Jwts.builder().setId(Claims.ID)//设置jti(JWT ID):是JWT的唯一标识,根据业务需要,这个可以设置为一个不重复的值,主要用来作为令牌的唯一标识。.setSubject("mijiu")//设置主题,一般为用户类型.setIssuedAt(new Date())//设置签发时间.addClaims(claims)//设置负载.signWith(SignatureAlgorithm.HS256, SECRET_KEY)//设置签名算法.setExpiration(new Date(System.currentTimeMillis() + EXPIRE_TIME))//设置令牌过期时间.compact();//生成令牌}/*** 解析token令牌* @param token token令牌* @return 负载*/public static Claims parseToken(String token) {return Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody();}/***  验证token令牌* @param token 令牌* @return 是否有效*/public static boolean validateToken(String token) {try {Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody();return true;} catch (Exception e) {return false;}}/*** 刷新Token* @param token 旧的Token令牌* @return 新的Token令牌*/public static String refreshToken(String token) {try {// 解析旧的Token,获取负载信息Claims claims = parseToken(token);// 生成新的Token,设置过期时间和签名算法等参数return generateToken(claims, claims.getSubject());} catch (Exception e) {throw new RuntimeException("无法刷新令牌!", e);}}/*** 从令牌中获取主题信息* @param token 令牌* @return 主题信息(用户类型)*/public static String getSubjectFromToken(String token) {try {Claims claims = parseToken(token); // 解析令牌,获取负载信息return claims.getSubject(); // 返回主题信息} catch (Exception e) {throw new RuntimeException("无法从令牌中获取主题。", e);}}}

编写测试

测试代码如下:

import com.mijiu.commom.util.JwtUtils;
import io.jsonwebtoken.Claims;
import org.junit.jupiter.api.Test;import java.util.Map;public class JwtTest {@Testpublic void testJwt() {// 设置JWT的payloadMap<String, Object> claims = Map.of("username", "mijiu", "role", "admin");// 生成JWTString jwt = JwtUtils.generateToken(claims, "secret");System.out.println("JWT: " + jwt);// 解析JWTClaims claims1 = JwtUtils.parseToken(jwt);// 获取完整的payloadString payload = claims1.toString();System.out.println("Payload: " + payload);}
}

作者目录结构

​​

运行测试代码

​​测试通过

2.配置项写到application.yml,交由spring容器管理依赖注入使用

jwt工具类如下:

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;import java.util.Date;
import java.util.Map;/*** @author mijiupro*/
@Data
@Component
@ConfigurationProperties(prefix = "jwt")
public class JwtUtils {private String secret;//密钥private  long expiration;//过期时间/*** 生成token令牌* @param claims JWT第二部分负载 payload 中存储的内容* @param subject 主题(用户类型)* @return token*/public  String generateToken(Map<String,Object> claims, String subject) {return Jwts.builder().setId(Claims.ID)//设置jti(JWT ID):是JWT的唯一标识,根据业务需要,这个可以设置为一个不重复的值,主要用来作为令牌的唯一标识。.setSubject("mijiu")//设置主题,一般为用户类型.setIssuedAt(new Date())//设置签发时间.addClaims(claims)//设置负载.signWith(SignatureAlgorithm.HS256, secret)//设置签名算法.setExpiration(new Date(System.currentTimeMillis() + expiration))//设置令牌过期时间.compact();//生成令牌}/*** 解析token令牌* @param token token令牌* @return 负载*/public  Claims parseToken(String token) {return Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();}/***  验证token令牌* @param token 令牌* @return 是否有效*/public  boolean validateToken(String token) {try {Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();return true;} catch (Exception e) {return false;}}/*** 刷新Token* @param token 旧的Token令牌* @return 新的Token令牌*/public  String refreshToken(String token) {try {// 解析旧的Token,获取负载信息Claims claims = parseToken(token);// 生成新的Token,设置过期时间和签名算法等参数return generateToken(claims, claims.getSubject());} catch (Exception e) {throw new RuntimeException("无法刷新令牌!", e);}}/*** 从令牌中获取主题信息* @param token 令牌* @return 主题信息(用户类型)*/public  String getSubjectFromToken(String token) {try {Claims claims = parseToken(token); // 解析令牌,获取负载信息return claims.getSubject(); // 返回主题信息} catch (Exception e) {throw new RuntimeException("无法从令牌中获取主题。", e);}}}
注意:此代码用到了lombok的@Data注解,来添加getter 和 setter 方法,请确保有该依赖依赖坐标:
<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional>
</dependency>

配置文件添加jwt的配置项

application.yml:

jwt:secret: 123456 #密钥expiration: 43200000 #过期时间 12h

​​

编写测试类

import com.mijiu.commom.util.JwtUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.HashMap;
import java.util.Map;/*** @author mijiupro*/@RestController
@RequestMapping("/test")
public class TestController {private final JwtUtils jwtUtils;public TestController(JwtUtils jwtUtils) {this.jwtUtils = jwtUtils;}@GetMapping("/get-token")public String getToken() {Map<String, Object> claims = new HashMap<>();claims.put("username", "mijiu");claims.put("role", "admin");return jwtUtils.generateToken(claims,"user");}@GetMapping("/parse-token/{token}")public  String parseToken(@PathVariable String token) {return jwtUtils.parseToken(token).toString();}
}

目录结构

​​

启动项目

请求jwt测试接口

生成token接口:

​​

复制token

请求解析token接口并路径传参传入复制的token

​​

测试成功。

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

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

相关文章

最短编辑距离问题与动态规划----LeetCode 72.编辑距离

动态规划&#xff08;Dynamic Programming, DP&#xff09;是解决复杂问题的一个强大工具&#xff0c;它将问题分解成更小的子问题&#xff0c;并使用这些子问题的解决方案来构建整体问题的解决方案。在深入探讨最短编辑距离问题之前&#xff0c;让我们先理解什么是动态规划&am…

让cgteamwork自动为Houdini载入相机,角色道具的abc文件

一 需求 最近接到个需求&#xff1a;在创建EFX文件时&#xff0c;自动加载动画出的缓存abc文件相机&#xff0c; 不用手动一个个的载入&#xff0c;还容易出错 ABC文件自动导入到Houndini里 二 过程/效果 在CGTeamwork里打开对应的镜头&#xff0c;下面的文件列表显示相机和角…

C# 更改系统的屏保设置

C# 更改系统的屏保设置 一、如果你想更改系统的屏保设置&#xff0c;可以使用P/Invoke调用SystemParametersInfo函数。 以下演示如何设置屏幕保护程序的等待时间&#xff08;也就是启动屏保前无操作的时间间隔&#xff09;&#xff0c; 示例代码&#xff1a; using System;…

C# 怎么判断屏幕是第几屏幕?屏幕是垂直还是水平?屏幕的分辨率?

一、怎么判断屏幕是第几屏幕&#xff1f; 可以使用System.Windows.Forms.Screen.AllScreens属性来获取所有已连接的屏幕&#xff0c;并根据鼠标位置或窗口的位置来判断它所在的屏幕索引。 using System; using System.Windows.Forms;// 获取鼠标当前位置所在的屏幕 Point cur…

OpenGL统一变量 Uniform Variables

OpenGL统一变量 Uniform Variables 在OpenGL着色器编程中&#xff0c;uniform变量是一种特殊的全局变量&#xff0c;它们的作用是在图形渲染管线的不同阶段&#xff08;如顶点着色器、片段着色器等&#xff09;共享常量数据。uniform变量的值由CPU端的应用程序设置&#xff0c…

格式化日期注解@JsonFormat的使用和TimeZone时区问题

JsonFormat的使用 目的 为了便于date类型字段的序列化和反序列化&#xff0c;需要在数据结构的Date、Timestamp、DateTime类型的字段上用JsonFormat注解进行注解 使用 JsonFormat注解是一个时间格式化注解&#xff0c;比如我们存储在mysql中的数据是date类型的&#xff0c;当…

自学Java的第58,59天

网络通信 网络通信三要素&#xff1a;ip地址&#xff0c;端口号&#xff0c;协议 ip地址 常用方法 写法 端口号 协议 UDP通信 快速入门 写法&#xff08;客户端&#xff09; &#xff08;服务端&#xff09; UDP通信 多发多收 TCP通信 写法&#xff08;客户端&#xff09; …

车载充电器(OBC)氮化镓(GaN)驱动(高压高功率)设计(第四篇)

上图来自于网络 1、GaN FET概念 GaN FET&#xff0c;全称为Gallium Nitride Field-Effect Transistor&#xff08;氮化镓场效应晶体管&#xff09;&#xff0c;是一种采用氮化镓&#xff08;Gallium Nitride, GaN&#xff09;材料制作的新型功率半导体器件。相较于传统的硅基…

前端常见30个bug以及解决方法

页面加载慢&#xff1a;可以通过优化代码、减少HTTP请求、使用CDN等方式来解决。 页面布局错乱&#xff1a;可以通过检查CSS样式、使用浏览器开发者工具进行调试来解决。 图片加载失败&#xff1a;可以通过检查图片路径、图片格式、网络连接等来解决。 点击事件无效&#xf…

物联网与智慧景区的未来:机遇与挑战并存

随着科技的不断发展&#xff0c;物联网技术在智慧景区中的应用越来越广泛&#xff0c;为旅游业带来了巨大的变革。然而&#xff0c;在物联网与智慧景区的未来发展中&#xff0c;机遇与挑战并存。本文将探讨物联网与智慧景区面临的机遇和挑战&#xff0c;并提出应对措施&#xf…

《幻兽帕鲁》解锁基地和工作帕鲁数量上限

帕鲁私服的游戏参数通常可通过配置文件 PalWorldSettings.ini 来进行修改&#xff0c;然而这个配置文件有个别参数对游戏不生效&#xff0c;让人很是头疼。没错&#xff01;我说的就是终端最大的帕鲁数量&#xff01; 其实还有另外一种更加高级的参数修改方式&#xff0c;那就…

使用Python和HTTP代理进行API请求

Python&#xff0c;这个简单易学又功能强大的编程语言&#xff0c;在网络爬虫、数据分析、自动化任务等领域都有着广泛的应用。而当我们需要从外部网站获取数据时&#xff0c;API&#xff08;应用程序接口&#xff09;就成了我们的得力助手。但有时候&#xff0c;某些网站会对A…

vscode 无法远程连接waiting the server log

使用版本 报错信息 相关日志 [17:32:59.765] > Waiting for server log... [17:32:59.801] > Waiting for server log... [17:32:59.831] > > * > * Visual Studio Code Server > * > * By using the software, you agree to > * the Visual Studio…

ip网络的三类地址及其相互关系

随着互联网的普及和发展&#xff0c;IP网络已成为全球范围内最重要的信息交换平台。在IP网络中&#xff0c;IP地址是每个设备在网络中的唯一标识&#xff0c;是实现网络通信的关键。虎观代理小二二将详细介绍IP网络中的三类地址&#xff0c;即A类、B类和C类地址&#xff0c;以及…

C++进阶--C++11线程库

目录 一、线程库&#xff08;thread&#xff09;1.1 线程对象的构造方式1.1.1 调用无参的构造函数1.1.2 调用带参的构造函数1.1.3 调用移动构造函数 1.2 thread提供的成员函数1.3 获取线程的id方式1.4 线程函数的参数问题1.5 join与detach1.5.1 join方式1.5.2 detach方式 二、互…

【C/C++ 12】C++98特性

目录 一、命名空间 二、缺省参数 三、函数重载 四、引用 五、内联函数 六、异常处理 一、命名空间 在C/C项目中&#xff0c;存在着大量的变量、函数和类&#xff0c;这些变量、函数和类都存在于全局作用域中&#xff0c;可能会导致命名冲突。 使用命名空间的目的就是对…

13.从桥接模式细品人生的几座桥

“物理学不存在了&#xff0c;今后也不会存在。”——《三体》 在《三体》中&#xff0c;有这样一个桥段&#xff0c;顶级的物理学家杨冬在三体文明超级计算机“智子”的干扰和误导下&#xff0c;得出了物理实验的结果在实验之前就会被某种力量确定的结论&#xff0c;导致自己…

2024牛客寒假算法基础集训营1(视频讲解全部题目)

2024牛客寒假算法基础集训营1&#xff08;题目全解&#xff09; ABCDEFGHIJKLM 2024牛客寒假算法基础集训营1&#xff08;视频讲解全部题目&#xff09; A #include<bits/stdc.h> #define endl \n #define deb(x) cout << #x << " " << …

springboot(ssm交友系统 在线社交论坛网站系统Java系统

springboot(ssm交友系统 在线社交论坛网站系统Java系统 开发语言&#xff1a;Java 框架&#xff1a;springboot&#xff08;可改ssm&#xff09; vue JDK版本&#xff1a;JDK1.8&#xff08;或11&#xff09; 服务器&#xff1a;tomcat 数据库&#xff1a;mysql 5.7&#…

elasticsearch重置密码操作

安装es的时候需要测试这个url&#xff1a;http://127.0.0.1:9200/ 出现弹窗让我输入账号和密码。我第一次登录&#xff0c;没有设置过账号和密码&#xff0c; 解决方法是&#xff1a;在es的bin目录下打开cmd窗口&#xff0c;敲命令&#xff1a;.\elasticsearch-reset-password…