Springboot3+Vue3实现JWT登录鉴权

news/2025/4/1 11:04:08/文章来源:https://www.cnblogs.com/shidawuyu/p/18795116

做鉴权原因:

管理系统的数据是敏感的,隐私的,每个角色的权限是不同的,必须在数据的增删改查操作时候对访问的用户进行权限验证

JWT(Json Web Token)

用于在网络应用间安全的传递消息。它以紧凑且自包含的方式,通过JSON对象在各方之间传递经过验证的信息。JWT通常由三部分组成,用点号(.)分隔:header.payload.signature

集成JWT(在pom中引入依赖)

<!--java-JWT坐标 --><dependency><groupId>com.auth0</groupId><artifactId>java-jwt</artifactId><version>4.4.0</version></dependency>

生成token

/*** 生成 JWT 令牌*/public static String createToken(String data,String sign) {return JWT.create().withAudience(data)//将userid-role保存到token里面作为载荷.withExpiresAt(DateUtil.offsetDay(new Date(),1))//1天后token过期.sign(Algorithm.HMAC256(sign));//以password作为token的密钥,使用HMAC256算法加密}

在***Service中创建token返回前端

String token = TokenUtil.createToken(dbUser.getId()+"-"+"管理员",dbUser.getPassword());
dbUser.setToken(token);

 

Token格式

"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiIxLeeuoeeQhuWRmCIsImV4cCI6MTc0MjkyMTk5Mn0.PH2OJMzhqZFuJz-aW5nWfE5wZk9fbM-tgxPql1_NNVI"

JWT拦截器对所有访问的接口进行验证

通过webConfig做一层拦截器拦截所有的接口

@Configuration
public class WebConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(jwtInterceptor()).addPathPatterns("/**")//校验规则所有接口.excludePathPatterns("/login","/register");//排除登录和注册接口}@Beanpublic JWTInterceptor jwtInterceptor(){return new JWTInterceptor();}
}

JWT拦截器

/*** JWT拦截器* 做拦截器的实现* 对Token进行拦截并进一步解析Token、验证Token,看看Token是否是合法的*/
@Component
public class JWTInterceptor implements HandlerInterceptor {@Resourceprivate UserService userService;@Resourceprivate ZuKeService zuKeService;@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {//1.从请求头拿到TokenString token=request.getHeader("token");if (StrUtil.isEmpty(token)){//如果没拿到,从参数中再拿一次token=request.getParameter("token");}//2.认证Tokenif (StrUtil.isBlank(token)){throw new CustomException("401","您无权操作");}Account account=null;try {//拿到Token载荷数据String audience = JWT.decode(token).getAudience().get(0);String[] split=audience.split("-");String userId=split[0];String role=split[1];//柑橘Token解析出来的userId去对应的表查询信息if ("管理员".equals(role)){account=userService.selectById(userId);} else if ("租客".equals(role)) {account=zuKeService.selectById(userId);}} catch (Exception e) {throw new CustomException("401","您无权操作");}if (account==null){throw new CustomException("401","您无权操作");}try {//用户加签 验证签名JWTVerifier jwtVerifier=JWT.require(Algorithm.HMAC256(account.getPassword())).build();jwtVerifier.verify(token);} catch (Exception e) {throw new CustomException("401","您无权操作");}return true;}
}

出现401错误,无权访问数据怎么办

 在Vue的request.js的拦截器里面添加统一的请求头Token

 request.js的代码

import axios from "axios";
import {ElMessage} from "element-plus";const request = axios.create({baseURL:'http://localhost:8080',//后端统一的请求地址timeout:30000 //后台接口时间
})
//request 拦截器
//可以自请求发送前对请求做一些处理
request.interceptors.request.use(config =>{//统一的数据传输格式为json,统一的编码utf-8config.headers['Content-Type']='application/json;charset=utf-8';//let user=JSON.parse(localStorage.getItem('pro1-user') || '{}');//config.headers['token']=user.token;// ✅ 安全获取 user(兼容 null 和异常情况)let user = {};try {const userStr = localStorage.getItem('pro1-user');user = userStr ? JSON.parse(userStr) : {};} catch (e) {console.error('解析 pro1-user 失败:', e);}// 仅当 token 存在时才添加到 headersif (user.token) {config.headers['token'] = user.token;} else {console.warn('Token 不存在,请求可能被后端拒绝');// 可选:跳转到登录页// window.location.href = '/login';
    }return config;
},error=>{return Promise.reject(error)
});
//response拦截器
//可以在接口响应后统一处理结果
request.interceptors.response.use(response =>{let res=response.data;//兼容服务端返回的字符串数据if(typeof  res === 'string'){//如果是string,转成jsonres = res ? JSON.parse(res) : res}if (res.code === '401'){ElMessage.error(res.msg);router.push('/login')}else {return res;}},error =>{//后端返回数据判断if (error.response.status === 404){ElMessage.error('未找到请求接口')}else if (error.response.status === 500){ElMessage.error('系统异常,请查看后端控制台报错')}else{console.error(error.message)}return Promise.reject(error)}
)
export default request

获取当前登录用户信息

@Component
public class TokenUtil {@ResourceUserService userService;@ResourceZuKeService zuKeService;static UserService stasticUserService;static ZuKeService stasticZuKeService;/*** 生成 JWT 令牌*/public static String createToken(String data,String sign) {return JWT.create().withAudience(data)//将userid-role保存到token里面作为载荷.withExpiresAt(DateUtil.offsetDay(new Date(),1))//1天后token过期.sign(Algorithm.HMAC256(sign));//以password作为token的密钥,使用HMAC256算法加密
    }/*** 获取当前登录用户信息* @return*/public static Account getCurrentUser(){Account account=null;HttpServletRequest request=((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();String token=request.getHeader("token");if (StrUtil.isEmpty(token)){//如果没拿到,从参数中再拿一次token=request.getParameter("token");}//拿到Token载荷数据String audience = JWT.decode(token).getAudience().get(0);String[] split=audience.split("-");String userId=split[0];String role=split[1];if ("管理员".equals(role)){return stasticUserService.selectById(userId);}else if ("租客".equals(role)){return stasticZuKeService.selectById(userId);}return null;}
}

在service方法里面获取当前登录用户的信息

 Account currentUser=TokenUtil.getCurrentUser();

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

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

相关文章

搜维尔科技:SenseGlove触觉反馈手套-自动化和培训的突破

触觉力反馈技术领导者SenseGlove和机器人操控创新者Aeon宣布推出HEART项目。此次合作将虚拟现实 、力反馈触觉手套(SenseGlove)和机器人系统(Aeon)集成在一起,以实现直观控制和实时力反馈,使机器人训练更加方便和有效。 自动化和培训的突破 由于产品需求不断变化以及机器…

搜维尔科技:Haption通用遥控控制器,可轻松集成到工业机器人控制中

TeleRobotics EXtender (TREX) 是一个专为力反馈远程操作而设计的框架。它为操作员必须在危险、具有挑战性或受限的环境中操作的情况提供了一种创新的解决方案,使他们能够在不暴露自己风险的情况下执行任务。借助 TREX,操作员可以手动控制远程机器人,具有很高的灵活性和精确…

Elasticsearch 的搜索功能

Elasticsearch 的搜索功能建议阅读顺序:Elasticsearch 入门 Elasticsearch 搜索(本文)1. 介绍 使用 Elasticsearch 最终目的是为了实现搜索功能,现在先将文档添加到索引中,接下来完成搜索的方法。 查询的分类:叶子查询:叶查询子句在特定字段中查找特定值,例如 match、t…

20242213 实验二《Python程序设计》实验报告

20242213 2024-2025-2 《Python程序设计》实验2报告 课程:《Python程序设计》 班级: 2422 姓名: 刘宗林 学号:20242213 实验教师:王志强 实验日期:2025年3月26日 必修/选修: 公选课 1.实验内容设计并编写一个计算器程序,实现基本运算功能;功能包括加、减、乘、除、取余…

《实战Java高并发程序设计(第3版)》 | PDF免费下载

《实战Java高并发程序设计(第3版)》主要介绍基于Java的并行程序设计基础、思路、方法和实战。第一,立足于并行程序基础,详细介绍Java并行程序设计的基本方法。第二,进一步详细介绍JDK对并行程序的强大支持,帮助读者快速、稳健地进行并行程序开发。第三,详细讨论“锁”的…

《DeepSeek原理与项目实战》 | PDF免费下载

DeepSeek 是一种基于 Transformer 架构的生成式 AI(Artificial Intelligence)大模型,融合了MoE 架构、混合精度训练、分布式优化等先进技术,具备强大的文本生成、多模态处理和任务定制化能力。本书系统性地介绍了开源大模型 DeepSeek-V3 的核心技术及其在实际开发中的深度应…

实现极限网关(INFINI Gateway)配置动态加载

还在停机更新 Gateway 配置,OUT 了。 今天和大家分享一个 Gateway 的功能:动态加载配置(也称热更新或热加载)。 这个功能可以在 Gateway 不停机的情况下更新配置并使之生效。 配置样例如下: path.data: data path.logs: logconfigs:auto_reload: true # set true to auto …

ubuntu20.04安装Synergy

问题 最近在Ubuntu20.04上安装新版本的Synergy遇到一些问题,Synergy最后一个支持ubuntu20.04的版本是v3.1.3-beta,下面是下载地址: https://symless.com/synergy/download/other 在安装的时候遇到下面的问题:提示依赖libssl1,然后尝试安装下面的软件包: sudo apt install…

Netty源码—7.ByteBuf原理二

大纲 9.Netty的内存规格 10.缓存数据结构 11.命中缓存的分配流程 12.Netty里有关内存分配的重要概念 13.Page级别的内存分配 14.SubPage级别的内存分配 15.ByteBuf的回收9.Netty的内存规格 (1)4种内存规格 (2)内存申请单位(1)4种内存规格 一.tiny:表示从0到512字节之间的内存大…

一文速通Python并行计算:03 Python多线程编程-多线程同步(上)—基于互斥锁、递归锁和信号量

在 Python 多线程编程中,线程同步是确保多个线程安全访问共享资源的关键技术。本篇文章介绍了互斥锁(Lock)、递归锁(RLock) 和 信号量(Semaphore) 的概念与应用。互斥锁用于防止多个线程同时修改数据,递归锁适用于嵌套锁定场景,而信号量则限制同时访问资源的线程数。一…

K3D|高效创建轻量级 k8s 集群 (run in dokcer)

k3d 是一个轻量级的包装器,用于在 docker 中运行 k3s(Rancher Lab 的最小 Kubernetes 发行版)什么是 K3S 官网:https://k3s.io/ 指南:https://rancher.com/docs/k3s/latest/en/ 中文版指南:https://docs.rancher.cn/docs/k3s/_index/ K3s 是一个轻量级的 Kubernetes 发行…

记录一下安装适用于intel 显卡的torch

支持的硬件和驱动如下按照表格安装好驱动。使用conda创建好虚拟环境(Python 3.9, 3.10, 3.11, 3.12, 3.13.)后,我的显卡是arc A580# For hardware listed in the table above, other than Intel Core™ Ultra Series 2 Mobile Processors (Arrow Lake-H), use the commands …