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

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

​​

测试成功。

相关文章:

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

⛰️个人主页: 蒾酒 &#x1f525;系列专栏&#xff1a;《spring boot实战》 &#x1f30a;山高路远&#xff0c;行路漫漫&#xff0c;终有归途。 目录 前置条件 jwt简介 导依赖 编写jwt工具类 1.配置项直接嵌入代码&#xff0c;通过类名.静态方法使用 2.配置项写到…...

git 克隆拉取代码出现私钥权限问题。

问题反馈&#xff1a; rootdd:~/android/boost-1.74-for-android-r20b# git clone https://github.com/liulilittle/boost-1.74-for-android-r20b.git Cloning into boost-1.74-for-android-r20b... WARNING: UNPROTECTED PRIVATE KEY FILE! Permissions 0777 for /root/…...

【5G NR】【一文读懂系列】移动通讯中使用的信道编解码技术-卷积码原理

目录 一、引言 二、卷积编码的发展历史 2.1 卷积码的起源 2.2 主要发展阶段 2.3 重要里程碑 三、卷积编码的基本概念 3.1 基本定义 3.2 编码器框图 3.3 编码多项式 3.4 网格图(Trellis)描述 四、MATLAB示例 一、引言 卷积编码&#xff0c;作为数字通信领域中的一项…...

揭开Markdown的秘籍:标题|文字样式|列表

&#x1f308;个人主页&#xff1a;聆风吟 &#x1f525;系列专栏&#xff1a;Markdown指南、网络奇遇记 &#x1f516;少年有梦不应止于心动&#xff0c;更要付诸行动。 文章目录 &#x1f4cb;前言一. ⛳️Markdown 标题二. ⛳️Markdown 文字样式2.1 &#x1f514;斜体2.2 &…...

移动最小二乘法

移动最小二乘法&#xff08;Moving Least Square&#xff0c;MLS&#xff09;主要应用于曲线与曲面拟合&#xff0c;该方法基于紧支撑加权函数&#xff08;即函数值只在有限大小的封闭域中定义大于零&#xff0c;而在域外则定义为零&#xff09;和多项式基函数&#xff0c;通过…...

【LeetCode】37. 解数独(困难)——代码随想录算法训练营Day30

题目链接&#xff1a;37. 解数独 题目描述 编写一个程序&#xff0c;通过填充空格来解决数独问题。 数独的解法需 遵循如下规则&#xff1a; 数字 1-9 在每一行只能出现一次。数字 1-9 在每一列只能出现一次。数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。&…...

VUE学习——属性绑定

属性绑定&#xff0c;就是给html添加id、class这样类似的操作。 <template><div v-bind:id"dynamicId"><div v-bind:class"dynamicClass">Test</div></div> </template><script>export default{data(){return{…...

vue3 之 通用组件统一注册全局

components/index.js // 把components中的所组件都进行全局化注册 // 通过插件的方式 import ImageView from ./ImageView/index.vue import Sku from ./XtxSku/index.vue export const componentPlugin {install (app) {// app.component(组件名字&#xff0c;组件配置对象)…...

[Java][算法 双指针]Day 02---LeetCode 热题 100---04~07

LeetCode 热题 100---04~07 第一题&#xff1a;移动零 思路 找到每一个为0的元素 然后移到数组的最后 但是需要注意的是 要在给定的数组原地进行修改 并且其他非零元素的相对顺序不能改变 我们采用双指针法 定义两个指针i和j i和j一开始分别都在0索引位置 然后判断j所…...

【问题解决】如何将一个服务器的docker迁移到另一个服务器

要将Docker容器从一台机器迁移到另一台机器&#xff0c;可以按照以下步骤操作&#xff1a; 在机器A上提交容器为镜像&#xff1a; 使用docker commit命令将运行中的容器保存为新的镜像。这里需要容器的ID或名称&#xff0c;以及你想要命名的目标镜像名。 docker commit [容器…...

C++单例模式详解

目录 0. 前言 1. 懒汉式单例模式 1.1 最简单的单例模式 1.2 防止内存泄漏 1.2.1 智能指针的方法 1.2.2 静态嵌套的方法 1.3 保证线程安全 1.4 C11版本的优雅解决方案 2. 饿汉式单例模式 0. 前言 起因是在程序中重复声明了一个单例模式的变量&#xff0c;后来程序怎么调…...

LLM应用开发与落地:流式响应

一、背景 最近智能客服产品给到一个游戏客户那边&#xff0c;客户那边的客服负责人体验后认为我们产品回答的准确率是还是比较高的。同时&#xff0c;他反馈了几个需要改进的地方&#xff0c;其中一个就是机器人回复慢。机器人回复慢有很多原因&#xff0c;也有优化方式&#…...

神经网络 | 基于 CNN 模型实现土壤湿度预测

Hi&#xff0c;大家好&#xff0c;我是半亩花海。在现代农业和环境监测中&#xff0c;了解土壤湿度的变化对于作物生长和水资源管理至关重要。通过深度学习技术&#xff0c;特别是卷积神经网络&#xff0c;我们可以利用过去的土壤湿度数据来预测未来的湿度趋势。本文将使用 Pad…...

江科大STM32 终

目录 SPI协议10.1 SPI简介W25Q64简介10.3 SPI软件读写W25Q6410.4 SPI硬件外设读写W25Q64 BKP备份寄存器、PER电源控制器、RTC实时时钟11.0 Unix时间戳代码示例&#xff1a;读写备份寄存器BKP11.2 RTC实时时钟 十二、PWR电源控制12.1 PWR简介代码示例&#xff1a;修改主频12.3 串…...

《MySQL 简易速速上手小册》第10章:未来趋势和进阶资源(2024 最新版)

文章目录 10.1 MySQL 在云计算和容器化中的应用10.1.1 基础知识10.1.2 重点案例&#xff1a;使用 Python 部署 MySQL 到 Kubernetes10.1.3 拓展案例 1&#xff1a;在 AWS RDS 上部署 MySQL 实例10.1.4 拓展案例 2&#xff1a;使用 Docker 部署 MySQL 10.2 MySQL 和 NoSQL 的整合…...

Stable Diffusion 模型下载:GhostMix(幽灵混合)

文章目录 模型介绍生成案例案例一案例二案例三案例四案例五案例六案例七案例八案例九案例十 下载地址 模型介绍 GhostMix 是绝对让你惊艳的模型&#xff0c;也是自己认为现在最强的2.5D模型。我认为模型的更新应该是基于现有的画面整体不大变的前提下&#xff0c;提高模型的成…...

django解决Table ‘xx‘ already exists的方法

1&#xff0c;首先看已存在的这个库表结构是什么样的&#xff0c;先让对应的model.py恢复到和他一样的字段 2&#xff0c;删除对应app下的migrations目录里面除__init__.py文件的其他所有文件 3&#xff0c;回到manage.py所在目录执行python manage.py makemigrations 4&#x…...

qt学习:arm摄像头+c调用v412框架驱动+qt调用v412框架驱动 显示摄像头画面

目录 跟内核进行数据通信的函数 编程步骤 c代码 头文件 打开摄像头文件 /dev/videox 获取当前主机上&#xff08;开发板&#xff09;摄像头列表信息 设置当前摄像头的画面格式 比如说 设置 采集图像的宽度为640 高度 480 在内核空间中&#xff0c;申请一个缓冲区队列…...

Linux 36.2@Jetson Orin Nano基础环境构建

Linux 36.2Jetson Orin Nano基础环境构建 1. 源由2. 步骤2.1 安装NVIDIA Jetson Linux 36.2系统2.2 必备软件安装2.3 基本远程环境2.3.1 远程ssh登录2.3.2 samba局域网2.3.3 VNC远程登录 2.4 开发环境安装 3. 总结 1. 源由 现在流行什么&#xff0c;也跟风来么一个一篇。当然&…...

牛客网SQL264:查询每个日期新用户的次日留存率

官网链接&#xff1a; 牛客每个人最近的登录日期(五)_牛客题霸_牛客网牛客每天有很多人登录&#xff0c;请你统计一下牛客每个日期新用户的次日留存率。 有一个登录(login。题目来自【牛客题霸】https://www.nowcoder.com/practice/ea0c56cd700344b590182aad03cc61b8?tpId82 …...

调用支付宝接口响应40004 SYSTEM_ERROR问题排查

在对接支付宝API的时候&#xff0c;遇到了一些问题&#xff0c;记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...

进程地址空间(比特课总结)

一、进程地址空间 1. 环境变量 1 &#xff09;⽤户级环境变量与系统级环境变量 全局属性&#xff1a;环境变量具有全局属性&#xff0c;会被⼦进程继承。例如当bash启动⼦进程时&#xff0c;环 境变量会⾃动传递给⼦进程。 本地变量限制&#xff1a;本地变量只在当前进程(ba…...

【位运算】消失的两个数字(hard)

消失的两个数字&#xff08;hard&#xff09; 题⽬描述&#xff1a;解法&#xff08;位运算&#xff09;&#xff1a;Java 算法代码&#xff1a;更简便代码 题⽬链接&#xff1a;⾯试题 17.19. 消失的两个数字 题⽬描述&#xff1a; 给定⼀个数组&#xff0c;包含从 1 到 N 所有…...

DAY 47

三、通道注意力 3.1 通道注意力的定义 # 新增&#xff1a;通道注意力模块&#xff08;SE模块&#xff09; class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...

什么是EULA和DPA

文章目录 EULA&#xff08;End User License Agreement&#xff09;DPA&#xff08;Data Protection Agreement&#xff09;一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA&#xff08;End User License Agreement&#xff09; 定义&#xff1a; EULA即…...

MySQL 8.0 OCP 英文题库解析(十三)

Oracle 为庆祝 MySQL 30 周年&#xff0c;截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始&#xff0c;将英文题库免费公布出来&#xff0c;并进行解析&#xff0c;帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...

uniapp中使用aixos 报错

问题&#xff1a; 在uniapp中使用aixos&#xff0c;运行后报如下错误&#xff1a; AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...

GC1808高性能24位立体声音频ADC芯片解析

1. 芯片概述 GC1808是一款24位立体声音频模数转换器&#xff08;ADC&#xff09;&#xff0c;支持8kHz~96kHz采样率&#xff0c;集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器&#xff0c;适用于高保真音频采集场景。 2. 核心特性 高精度&#xff1a;24位分辨率&#xff0c…...

python报错No module named ‘tensorflow.keras‘

是由于不同版本的tensorflow下的keras所在的路径不同&#xff0c;结合所安装的tensorflow的目录结构修改from语句即可。 原语句&#xff1a; from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后&#xff1a; from tensorflow.python.keras.lay…...

Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习)

Aspose.PDF 限制绕过方案&#xff1a;Java 字节码技术实战分享&#xff08;仅供学习&#xff09; 一、Aspose.PDF 简介二、说明&#xff08;⚠️仅供学习与研究使用&#xff09;三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...