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

Spring Boot + JWT 实现无状态认证

1. JWTJWTJSON Web Token是一种开放标准RFC 7519用于在网络应用环境间安全地将信息作为 JSON 对象传输。JWT 是目前最流行的跨域认证解决方案特别适合前后端分离的架构。1.1 JWT 的结构JWT 由三部分组成用点号.分隔xxxxx.yyyyy.zzzzz │ │ │ │ │ └── Signature签名 │ └───────── Payload负载 └──────────────── Header头部Header包含令牌类型和签名算法{alg:HS256,typ:JWT}Payload包含声明claims如用户信息、过期时间等{username:zhangsan,iat:1516239022,exp:1516242622}Signature使用密钥对前两部分进行签名确保令牌不被篡改1.2 JWT 的优势优势说明无状态服务器不需要保存会话信息令牌自包含用户信息跨域支持天然支持 CORS适合前后端分离架构扩展性强令牌中可以携带自定义信息安全性高使用签名防止篡改支持过期时间2. 项目架构┌─────────────────────────────────────────────────────────────┐ │ 客户端 (Vue 3) │ │ ┌──────────────┐ ┌──────────────┐ ┌────────────────────┐ │ │ │ 登录请求 │ │ 存储 Token │ │ 请求携带 Token │ │ │ └──────────────┘ └──────────────┘ └────────────────────┘ │ └─────────────────────────────────────────────────────────────┘ │ │ HTTP/REST ▼ ┌─────────────────────────────────────────────────────────────┐ │ 服务端 (Spring Boot) │ │ ┌──────────────┐ ┌──────────────┐ ┌────────────────────┐ │ │ │ 生成 Token │ │ 验证 Token │ │ 授权访问资源 │ │ │ │ (JwtUtil) │ │ (JwtFilter) │ │ (SecurityConfig) │ │ │ └──────────────┘ └──────────────┘ └────────────────────┘ │ └─────────────────────────────────────────────────────────────┘3. 核心组件实现3.1 JwtUtil - JWT 工具类负责生成、解析和验证 JWT 令牌。ComponentpublicclassJwtUtil{// 使用 HS256 算法生成密钥privatefinalKeykeyKeys.secretKeyFor(SignatureAlgorithm.HS256);AutowiredprivateAppConfigappConfig;/** * 生成 JWT 令牌 * param username 用户名 * return JWT 令牌字符串 */publicStringgenerateToken(Stringusername){MapString,ObjectclaimsnewHashMap();claims.put(username,username);returnJwts.builder().setClaims(claims)// 设置自定义声明.setSubject(username)// 设置主题用户名.setIssuedAt(newDate())// 设置签发时间.setExpiration(newDate(System.currentTimeMillis()getExpirationTime()))// 设置过期时间.signWith(key)// 使用密钥签名.compact();// 生成令牌}/** * 从令牌中提取用户名 * param token JWT 令牌 * return 用户名 */publicStringextractUsername(Stringtoken){ClaimsclaimsJwts.parserBuilder().setSigningKey(key)// 设置验证密钥.build().parseClaimsJws(token)// 解析令牌.getBody();// 获取声明体returnclaims.getSubject();}/** * 验证令牌是否有效 * param token JWT 令牌 * return 是否有效 */publicbooleanvalidateToken(Stringtoken){try{Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(token);returntrue;// 解析成功令牌有效}catch(Exceptione){returnfalse;// 解析失败令牌无效或过期}}}关键点说明使用Keys.secretKeyFor(SignatureAlgorithm.HS256)生成安全的密钥setExpiration()设置令牌过期时间增强安全性validateToken()捕获所有异常确保令牌验证的健壮性3.2 JwtFilter - JWT 过滤器拦截请求验证 JWT 令牌的有效性。ComponentpublicclassJwtFilterextendsOncePerRequestFilter{privatestaticfinalLoggerloggerLoggerFactory.getLogger(JwtFilter.class);AutowiredprivateJwtUtiljwtUtil;OverrideprotectedvoiddoFilterInternal(HttpServletRequestrequest,HttpServletResponseresponse,FilterChainchain)throwsServletException,IOException{// 从请求头中获取令牌StringauthorizationHeaderrequest.getHeader(Authorization);Stringtokennull;Stringusernamenull;// 检查授权头提取 Bearer Tokenif(authorizationHeader!nullauthorizationHeader.startsWith(Bearer )){tokenauthorizationHeader.substring(7);// 去掉 Bearer 前缀try{usernamejwtUtil.extractUsername(token);}catch(Exceptione){logger.error(Error extracting username from token: {},e.getMessage());}}// 验证令牌并设置认证上下文if(username!nullSecurityContextHolder.getContext().getAuthentication()null){if(jwtUtil.validateToken(token)){// 创建认证令牌UsernamePasswordAuthenticationTokenauthTokennewUsernamePasswordAuthenticationToken(username,null,null);authToken.setDetails(newWebAuthenticationDetailsSource().buildDetails(request));// 设置安全上下文SecurityContextHolder.getContext().setAuthentication(authToken);}}chain.doFilter(request,response);}}关键点说明继承OncePerRequestFilter确保每个请求只过滤一次从Authorization头中提取Bearer Token使用SecurityContextHolder设置认证信息供后续业务使用3.3 SecurityConfig - 安全配置配置 Spring Security定义安全规则和认证方式。ConfigurationEnableWebSecuritypublicclassSecurityConfig{AutowiredprivateJwtFilterjwtFilter;BeanpublicSecurityFilterChainsecurityFilterChain(HttpSecurityhttp)throwsException{http// 配置 CORS.cors(cors-cors.configurationSource(corsConfigurationSource()))// 禁用 CSRF前后端分离不需要.csrf(csrf-csrf.disable())// 配置请求授权.authorizeHttpRequests(authorize-authorize// 允许匿名访问的路径.requestMatchers(/api/v1/users/register,/api/v1/users/login,/api/v1/users/security-question,/api/v1/users/reset-password,/api/v1/captcha/**).permitAll()// AI 相关接口允许匿名访问.requestMatchers(/api/v1/ai-analysis/**,/api/v1/ai-assistant/**).permitAll()// Swagger 文档允许访问.requestMatchers(/swagger-ui.html,/swagger-ui/**,/v3/api-docs/**).permitAll()// 其他请求需要认证.anyRequest().authenticated())// 添加 JWT 过滤器.addFilterBefore(jwtFilter,UsernamePasswordAuthenticationFilter.class);returnhttp.build();}BeanpublicCorsConfigurationSourcecorsConfigurationSource(){CorsConfigurationconfigurationnewCorsConfiguration();configuration.setAllowedOrigins(Arrays.asList(http://localhost:5173));configuration.setAllowedMethods(Arrays.asList(GET,POST,PUT,DELETE,OPTIONS));configuration.setAllowedHeaders(Arrays.asList(Content-Type,Authorization));configuration.setAllowCredentials(true);UrlBasedCorsConfigurationSourcesourcenewUrlBasedCorsConfigurationSource();source.registerCorsConfiguration(/**,configuration);returnsource;}}关键点说明禁用 CSRF 保护前后端分离架构不需要配置白名单路径允许匿名访问登录、注册等接口使用addFilterBefore()将 JWT 过滤器添加到 Spring Security 过滤器链中4. 认证流程4.1 登录流程1. 用户发送登录请求 POST /api/v1/users/login { username: zhangsan, password: password123, captcha: a3f8 } 2. UserController 接收请求验证用户名密码 3. 验证成功调用 JwtUtil.generateToken(username) 生成 JWT 4. 返回响应包含 JWT 令牌 { success: true, data: { token: eyJhbGciOiJIUzI1NiIs..., username: zhangsan } } 5. 前端存储 TokenlocalStorage 或 sessionStorage4.2 请求认证流程1. 用户访问受保护资源请求头携带 Token Authorization: Bearer eyJhbGciOiJIUzI1NiIs... 2. JwtFilter 拦截请求从 Header 提取 Token 3. 验证 Token 有效性签名、过期时间 4. 验证通过设置 SecurityContext 认证信息 5. 请求到达 Controller执行业务逻辑 6. 返回业务数据5. 代码示例5.1 登录接口实现RestControllerRequestMapping(/api/v1/users)publicclassUserController{AutowiredprivateUserServiceuserService;AutowiredprivateJwtUtiljwtUtil;privateBCryptPasswordEncoderpasswordEncodernewBCryptPasswordEncoder();PostMapping(/login)publicUserResponselogin(ValidRequestBodyUserLoginRequestrequest,HttpServletRequesthttpRequest){// 1. 验证验证码Stringcaptcharequest.getCaptcha();if(!validateCaptcha(captcha,httpRequest.getSession())){thrownewRuntimeException(验证码错误);}// 2. 验证用户名密码UseruseruserService.login(request.getUsername(),request.getPassword());// 3. 生成 JWT TokenStringtokenjwtUtil.generateToken(user.getUsername());// 4. 构建响应UserResponseresponsenewUserResponse();response.setToken(token);response.setUsername(user.getUsername());response.setEmail(user.getEmail());// ... 其他用户信息returnresponse;}}5.2 受保护接口示例RestControllerRequestMapping(/api/v1/food-records)publicclassFoodRecordController{GetMappingpublicListFoodRecordgetRecords(RequestParamStringusername){// 由于 JwtFilter 已经验证过 Token// 这里可以直接获取当前认证用户AuthenticationauthSecurityContextHolder.getContext().getAuthentication();StringcurrentUserauth.getName();// 验证只能查询自己的记录if(!currentUser.equals(username)){thrownewRuntimeException(无权访问其他用户的数据);}returnfoodRecordService.findByUsername(username);}}6. 前端集成6.1 登录后存储 Token// 登录成功保存 Tokenconstloginasync(credentials){constresponseawaitapi.post(/api/v1/users/login,credentials);const{token,username}response.data;// 存储到 localStoragelocalStorage.setItem(token,token);localStorage.setItem(username,username);returnresponse.data;};6.2 请求拦截器添加 Token// Axios 请求拦截器api.interceptors.request.use(config{consttokenlocalStorage.getItem(token);if(token){config.headers.AuthorizationBearer${token};}returnconfig;},errorPromise.reject(error));6.3 响应拦截器处理 401// Axios 响应拦截器api.interceptors.response.use(responseresponse.data,error{if(error.response?.status401){// Token 过期或无效清除存储并跳转登录页localStorage.removeItem(token);window.location.href/;}returnPromise.reject(error);});7. 安全注意事项7.1 密钥管理生产环境密钥应存储在环境变量或配置中心不要硬编码密钥轮换定期更换密钥旧令牌会自然失效密钥强度使用足够强度的密钥HS256 自动生成7.2 令牌安全风险防护措施XSS 攻击使用 httpOnly Cookie 存储令牌或做好 XSS 防护CSRF 攻击前后端分离天然免疫 CSRF但仍需验证 Origin令牌泄露设置合理的过期时间通常 1-24 小时重放攻击结合时间戳和随机数或使用短期令牌7.3 传输安全生产环境必须使用 HTTPS敏感接口增加额外的验证如密码修改需要旧密码

相关文章:

Spring Boot + JWT 实现无状态认证

1. JWT JWT(JSON Web Token)是一种开放标准(RFC 7519),用于在网络应用环境间安全地将信息作为 JSON 对象传输。JWT 是目前最流行的跨域认证解决方案,特别适合前后端分离的架构。 1.1 JWT 的结构 JWT 由三…...

知网AI率30%50%80%哪个最难降?比话降AI知网专精方案!

知网AI率30%50%80%哪个最难降?比话降AI知网专精方案! 很多硕博毕业生有个直觉:知网 AI 率 80% 比 30% 难降很多。这个直觉只对了一半。 真相是:难度不是看数字高低,是看「工具的技术路线对不对知网的算法」。一篇 80% …...

Speechless:你的微博数字记忆永久保存方案,告别内容丢失焦虑

Speechless:你的微博数字记忆永久保存方案,告别内容丢失焦虑 【免费下载链接】Speechless 把新浪微博的内容,导出成 PDF 文件进行备份的 Chrome Extension。 项目地址: https://gitcode.com/gh_mirrors/sp/Speechless 你是否曾经历过精…...

5分钟掌握暗黑2存档修改秘籍:彻底告别重复刷怪烦恼

5分钟掌握暗黑2存档修改秘籍:彻底告别重复刷怪烦恼 【免费下载链接】d2s-editor 项目地址: https://gitcode.com/gh_mirrors/d2/d2s-editor 还在为暗黑破坏神2无尽的重复刷怪而烦恼吗?想体验各种强力build却不想花费数百小时练级刷装备&#xff…...

终极指南:如何用WarcraftHelper彻底解决魔兽争霸3的现代系统兼容性问题

终极指南:如何用WarcraftHelper彻底解决魔兽争霸3的现代系统兼容性问题 【免费下载链接】WarcraftHelper Warcraft III Helper , support 1.20e, 1.24e, 1.26a, 1.27a, 1.27b 项目地址: https://gitcode.com/gh_mirrors/wa/WarcraftHelper 你是否还在为魔兽争…...

计算机毕业设计:Python医疗文本挖掘与可视化决策平台 Flask框架 随机森林 机器学习 疾病数据 智慧医疗 深度学习(建议收藏)✅

博主介绍:✌全网粉丝10W,前互联网大厂软件研发、集结硕博英豪成立工作室。专注于计算机相关专业项目实战6年之久,选择我们就是选择放心、选择安心毕业✌ > 🍅想要获取完整文章或者源码,或者代做,拉到文章底部即可与…...

Matlab实战:基于EGM2008模型与球谐函数解析全球重力梯度场

1. 地球重力场模型与EGM2008简介 地球重力场是描述地球质量分布的重要物理场,它影响着卫星轨道、海平面变化甚至我们日常使用的导航系统。想象一下,如果把地球比作一个表面凹凸不平的土豆,重力场就是描述这个"土豆"各处引力大小的地…...

别再只怪芯片了!拆解一个智能家居产品,看它的EMC静电防护设计到底哪里出了问题

智能家居静电防护失效分析:从产品拆解看EMC设计盲区 最近一位做智能门锁的创业者朋友向我吐槽:他们的旗舰产品在北方冬季频繁出现用户触摸时死机的情况,售后返修率飙升到15%。拆机检测却显示主板芯片完好,问题究竟出在哪里&#…...

计算机毕业设计:Python智慧医疗数据可视化与疾病预测系统 Flask框架 随机森林 机器学习 疾病数据 智慧医疗 深度学习(建议收藏)✅

博主介绍:✌全网粉丝10W,前互联网大厂软件研发、集结硕博英豪成立工作室。专注于计算机相关专业项目实战6年之久,选择我们就是选择放心、选择安心毕业✌ > 🍅想要获取完整文章或者源码,或者代做,拉到文章底部即可与…...

题目五:抽象类 + 接口 混合实现

编程要求:抽象类 Machine:抽象方法 work(),普通方法 start();接口 Clean:抽象方法 clean();类 Robot继承抽象类 Machine 实现接口 Clean;实现所有未实现的方法;测试创建机器人对象&…...

大模型动态计算:按需推理更高效

一种让大语言模型更智能地思考难题的方法 这项新技术使大语言模型能够根据问题的难度,动态调整用于推理的计算量。 为了使大语言模型在回答较难问题时更加准确,研究人员可以让模型花费更多时间来思考潜在解决方案。但是,赋予大语言模型这种能…...

集合进阶(Collection)

一、集合概述和分类1.1 集合的分类如下图所示:一类是单列集合元素是一个一个的,另一类是双列集合元素是一对一对的。 主要学习Collection单列集合。Collection是单列集合的根接口,也称之为顶层接口,Collection接口下面又有两个子接…...

通过AxisApi中转站使用国外API大模型教程

前言:所有的国外大模型想不通过中转站直接使用,其实是很麻烦的的事情,就拿codex来说,需要一个谷歌账号,没有谷歌账号需要注册,注册还必须要使用国外的手机号码和验证码校验审核,流程很繁琐&…...

坐北朝南教育集团

在教育行业不断发展的当下,家长和学生在选择教育机构时常常面临诸多困扰,寻找一家口碑好、教学质量高的教育集团成为了关键。坐北朝南教育集团作为辽沈地区知名的综合教育航母,在解决教育领域痛点方面表现出色,成为众多家长和学生…...

终极跨平台Steam创意工坊下载指南:WorkshopDL让你的模组之旅更简单

终极跨平台Steam创意工坊下载指南:WorkshopDL让你的模组之旅更简单 【免费下载链接】WorkshopDL WorkshopDL - The Best Steam Workshop Downloader 项目地址: https://gitcode.com/gh_mirrors/wo/WorkshopDL 你是否在Epic Games Store或GOG平台购买了心仪的…...

我开会用了之后从怀疑到真香!2026华为手机语音转文字真后悔没早用

我上周差点因为漏记项目评审会的核心需求背锅,前前后后踩了N多会议记录的坑,用过不下10款语音转文字工具,掏心窝子说一句:听脑AI是同类工具中最值得职场人用的,没有之一。之前我真的不信什么语音转文字能解决所有问题&…...

在MacBook Pro上构建工业物联网数据采集:libmodbus实战指南

1. 为什么选择MacBook Pro作为工业物联网开发平台 工业物联网开发通常需要频繁的现场调试和设备对接,传统工控机笨重且不便携。MacBook Pro凭借其出色的性能表现和稳定的macOS系统,正在成为工程师们的新宠。我去年参与一个智慧农业项目时,就深…...

K8s日志太乱?试试用Docker插件把容器日志直通Grafana Loki(保姆级教程)

K8s日志太乱?试试用Docker插件把容器日志直通Grafana Loki(保姆级教程) 在容器化应用的日常运维中,日志管理往往是最容易被忽视却又最令人头疼的环节。想象一下这样的场景:你的开发环境运行着十几个Docker容器&#xf…...

VideoDownloadHelper:3步实现全网视频下载的智能工具

VideoDownloadHelper:3步实现全网视频下载的智能工具 【免费下载链接】VideoDownloadHelper Chrome Extension to Help Download Video for Some Video Sites. 项目地址: https://gitcode.com/gh_mirrors/vi/VideoDownloadHelper VideoDownloadHelper是一款专…...

原来市面上这些匹克球装备制造厂,都有啥独特之处?

匹克球运动近年来愈发火热,市面上的匹克球装备制造厂也如雨后春笋般涌现,每个品牌都有其独特的优势和特点。下面为你介绍其中一部分具有代表性的厂家及其独特之处。凯瑞麟体育用品:科技与文化的融合凯瑞麟体育用品成立于2025年11月&#xff0…...

从业者必看:医药资质认证服务核心知识梳理

如果你是初创医疗器械贸易商创始人、医美诊所创业者、连锁药店负责人或是医药电商运营人员,正面临缺证无法入驻平台、自行办理流程繁琐反复被驳回、赶大促节点急需下证等问题,想要了解医药资质认证服务相关内容,这篇科普内容会为你梳理清楚全…...

AI 绘图新进展:GPTimage2 系列(含 4K 超清版)全量上线及直连 API 体验指南

随着 AIGC(人工智能生成内容)技术的快速迭代,近期备受关注的 GPTimage2 系列模型已全量上线。作为 AI 绘图领域的新晋生力军,GPTimage2 在图像生成质量、细节刻画上展现出了极强的竞争力。特别值得一提的是,本次不仅上…...

太流批了,发票合并神器

今天给大家推荐两款软件,一款是图片转PDF,一款是发票合并工具。有需要的小伙伴可以下载收藏。 第一款:png2pdf png2pdf是一款png图片转PDF的小工具,这类的工具之前也有推荐过,但是今天这款比较特殊。 只要把图片拖入软…...

告别龟速下载!用这个离线驱动包5分钟搞定DBeaver连接所有数据库

5分钟极速配置:DBeaver全量离线驱动包实战指南 每次打开DBeaver准备连接新数据库时,那个转个不停的驱动下载进度条是不是让你抓狂?尤其是在企业内网环境或网络不稳定时,等待驱动下载的过程简直能让人把咖啡喝成凉茶。今天要分享的…...

【JSON-RPC远程过程调用组件库】测试报告

RPC 框架测试报告一、项目背景 本项目是一个基于 C 实现的轻量级 RPC(远程过程调用)框架,旨在解决分布式系统中服务间通信的复杂性。框架提供三大核心能力:基础 RPC 远程调用(同步/异步/回调三种模式)、基于…...

Python全栈实战:前后端分离开发核心要点

后端API搭建FastAPI与Flask是Python全栈开发的主流后端框架选择。两者均支持RESTful API开发,但适用场景不同:FastAPI代码示例(高性能方案):from fastapi import FastAPI app FastAPI()app.get("/items/{item_id…...

90%的程序员都不知道,转大模型根本不用从头学深度学习

文章目录前言一、大模型时代,传统深度学习的学习路径已经彻底过时了1.1 以前做AI,确实得先学深度学习1.2 现在做AI,更像是开汽车1.3 90%的大模型岗位,根本不需要深度学习底层知识二、90%的大模型开发工作,到底在做什么…...

让机房管理告别粗放,每一寸资源都物尽其用

对于机房运维人员而言,U 位管理看似是基础小事,却是决定机房运维效率、资产安全与合规水平的关键。当前,不少企业机房、单位机房仍沿用传统人工管理模式,机柜 U 位全靠记忆、台账全靠 Excel、盘点全靠熬夜,看似节省了成…...

Git 入门教程:从命令行到 IDE 集成

文章目录Git 入门教程:从命令行到 IDE 集成一、环境准备与初始配置1.1 安装 Git1.2 配置用户身份2.2 查看仓库状态2.3 添加文件到暂存区2.4 提交文件到本地仓库2.5 查看历史版本2.6 版本回退2.7 删除文件三、Git 分支操作(多人协作核心)3.1 分…...

Android 14 + Linux 6.1 平台 RTL8822CE Wi‑Fi 适配实战:从 PCI 已枚举到成功扫描热点

摘要 在 Android 14 Linux 6.1 的移植过程中,RTL8822CE Wi‑Fi 很容易出现一种“硬件已经被 PCI 枚举到,但系统就是没有 wlan0”的尴尬状态。本文复盘一次完整的 RTL8822CE 适配过程,最终定位出两个连续阻塞点:第一,目…...