SpringBoot 集成 JWT 实现登录认证 + 权限拦截(电商系统实战,代码可直接复制)

news2026/4/13 8:57:34
一、开篇引言做前后端分离的电商管理系统登录认证与权限控制是绝对的核心功能也是 Java 后端面试的高频考点。你是不是也遇到过这些问题前后端分离项目Session 共享困难无法用传统 Session 做登录认证不知道如何实现无状态的用户登录接口安全无法保障分不清 JWT 的原理、结构踩坑后无法排查问题不知道如何结合 SpringBoot 实现登录拦截、权限校验防止未授权访问本文结合你正在做的电商管理系统从原理到实战完整实现 SpringBoot 集成 JWT 实现登录认证 全局权限拦截包含完整可复制代码、高频踩坑总结15 分钟就能搭建企业级登录认证体系完美适配你的项目。本文基于 SpringBoot 2.7.x JWT 0.11.5适合 Java 后端初学者、正在做前后端分离项目的同学尤其适合大二计算机专业学生练手电商项目。二、核心知识点先懂原理再写代码1. JWT 核心原理JWTJSON Web Token是一种无状态的身份认证方案核心是将用户身份信息加密后生成 Token前端存储 Token每次请求携带 Token 到后端后端解密验证身份无需在服务端存储 Session完美适配前后端分离项目。2. JWT 结构拆解JWT 由 3 部分组成用 . 分隔Header头部存储签名算法如 HS256、Token 类型Payload载荷存储用户信息如用户 ID、用户名、过期时间等自定义声明Signature签名用密钥对 HeaderPayload 加密生成防止 Token 被篡改3. 核心优势无状态服务端无需存储 Session扩展性强适合分布式系统跨域友好完美适配前后端分离、移动端等场景安全性高签名机制防止 Token 被篡改可设置过期时间保障安全三、环境准备直接复制无需修改!--SpringBootWeb核心依赖--dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependency!--JWT核心依赖0.11.5稳定版--dependencygroupIdio.jsonwebtoken/groupIdartifactIdjjwt-api/artifactIdversion0.11.5/version/dependencydependencygroupIdio.jsonwebtoken/groupIdartifactIdjjwt-impl/artifactIdversion0.11.5/versionscoperuntime/scope/dependencydependencygroupIdio.jsonwebtoken/groupIdartifactIdjjwt-jackson/artifactIdversion0.11.5/versionscoperuntime/scope/dependency!--MyBatis-Plus复用电商系统已有依赖--dependencygroupIdcom.baomidou/groupIdartifactIdmybatis-plus-boot-starter/artifactIdversion3.5.3/version/dependency!--Lombok简化代码--dependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactIdoptionaltrue/optional/dependency2. application.yml 配置#JWT配置 jwt:# 密钥生产环境请更换为复杂密钥建议16位以上 secret:my-secret-key-1234567890# 过期时间单位毫秒7天7*24*60*60*1000604800000 expiration:604800000#Token前缀 token-prefix:Bearer# 请求头名称 header:Authorization四、核心代码实现严格拆分「工具类 拦截器 接口」4.1 JWT 工具类核心生成 / 解析 Tokenpackagecom.example.demo.utils;importio.jsonwebtoken.Claims;importio.jsonwebtoken.Jwts;importio.jsonwebtoken.SignatureAlgorithm;importio.jsonwebtoken.security.Keys;importorg.springframework.beans.factory.annotation.Value;importorg.springframework.stereotype.Component;importjavax.crypto.SecretKey;importjava.nio.charset.StandardCharsets;importjava.util.Date;importjava.util.HashMap;importjava.util.Map;/** * JWT 工具类 * 用于生成 Token、解析 Token、验证 Token 有效性 */ComponentpublicclassJwtUtils{Value(${jwt.secret})privateStringsecret;Value(${jwt.expiration})privateLongexpiration;Value(${jwt.token-prefix})privateStringtokenPrefix;/** * 生成密钥 */privateSecretKeygetSignKey(){returnKeys.hmacShaKeyFor(secret.getBytes(StandardCharsets.UTF_8));}/** * 生成 Token * param userId 用户ID * param username 用户名 * return 生成的 Token */publicStringgenerateToken(LonguserId,Stringusername){MapString,ObjectclaimsnewHashMap();claims.put(userId,userId);claims.put(username,username);returncreateToken(claims,username);}/** * 创建 Token */privateStringcreateToken(MapString,Objectclaims,Stringsubject){DatenownewDate();DateexpireDatenewDate(now.getTime()expiration);returnJwts.builder().setClaims(claims)// 自定义载荷.setSubject(subject)// 主题.setIssuedAt(now)// 签发时间.setExpiration(expireDate)// 过期时间.signWith(getSignKey(),SignatureAlgorithm.HS256)// 签名.compact();}/** * 解析 Token获取载荷 */publicClaimsparseToken(Stringtoken){returnJwts.parserBuilder().setSigningKey(getSignKey()).build().parseClaimsJws(token).getBody();}/** * 从 Token 中获取用户ID */publicLonggetUserIdFromToken(Stringtoken){ClaimsclaimsparseToken(token);returnLong.valueOf(claims.get(userId).toString());}/** * 验证 Token 是否过期 */publicBooleanisTokenExpired(Stringtoken){ClaimsclaimsparseToken(token);returnclaims.getExpiration().before(newDate());}/** * 验证 Token 有效性 */publicBooleanvalidateToken(Stringtoken){try{return!isTokenExpired(token);}catch(Exceptione){returnfalse;}}/** * 去除 Token 前缀 */publicStringremovePrefix(Stringtoken){if(token.startsWith(tokenPrefix)){returntoken.substring(tokenPrefix.length()).trim();}returntoken;}}4.2 JWT 拦截器全局权限拦截验证 Tokenpackagecom.example.demo.interceptor;importcom.example.demo.utils.JwtUtils;importorg.springframework.stereotype.Component;importorg.springframework.web.servlet.HandlerInterceptor;importjavax.annotation.Resource;importjavax.servlet.http.HttpServletRequest;importjavax.servlet.http.HttpServletResponse;/** * JWT 拦截器 * 拦截所有请求验证 Token 有效性实现登录认证 */ComponentpublicclassJwtInterceptorimplementsHandlerInterceptor{ResourceprivateJwtUtilsjwtUtils;OverridepublicbooleanpreHandle(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler)throwsException{// 1. 处理跨域预检请求OPTIONS 直接放行if(OPTIONS.equals(request.getMethod())){returntrue;}// 2. 从请求头获取 TokenStringtokenrequest.getHeader(Authorization);// 3. Token 为空返回未授权if(tokennull||token.isEmpty()){response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);response.getWriter().write({\code\:401,\msg\:\未登录请先登录\});returnfalse;}// 4. 去除 Token 前缀tokenjwtUtils.removePrefix(token);// 5. 验证 Token 有效性if(!jwtUtils.validateToken(token)){response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);response.getWriter().write({\code\:401,\msg\:\Token 已过期请重新登录\});returnfalse;}// 6. Token 有效放行请求returntrue;}}4.3 拦截器配置类注册拦截器配置放行路径packagecom.example.demo.config;importcom.example.demo.interceptor.JwtInterceptor;importorg.springframework.context.annotation.Configuration;importorg.springframework.web.servlet.config.annotation.InterceptorRegistry;importorg.springframework.web.servlet.config.annotation.WebMvcConfigurer;importjavax.annotation.Resource;/** * WebMvc 配置类 * 注册 JWT 拦截器配置拦截/放行路径 */ConfigurationpublicclassWebMvcConfigimplementsWebMvcConfigurer{ResourceprivateJwtInterceptorjwtInterceptor;OverridepublicvoidaddInterceptors(InterceptorRegistryregistry){registry.addInterceptor(jwtInterceptor)// 拦截所有请求.addPathPatterns(/**)// 放行登录、注册等接口电商系统核心放行路径.excludePathPatterns(/user/login,// 登录接口/user/register,// 注册接口/captcha/get,// 验证码接口/doc.html,// Knife4j 接口文档/webjars/**,/v3/api-docs/**);}}4.4 登录接口实现电商系统用户登录packagecom.example.demo.controller;importcom.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;importcom.example.demo.common.Result;importcom.example.demo.entity.User;importcom.example.demo.service.UserService;importcom.example.demo.utils.JwtUtils;importorg.springframework.util.DigestUtils;importorg.springframework.web.bind.annotation.PostMapping;importorg.springframework.web.bind.annotation.RequestBody;importorg.springframework.web.bind.annotation.RequestMapping;importorg.springframework.web.bind.annotation.RestController;importjavax.annotation.Resource;importjava.util.HashMap;importjava.util.Map;/** * 用户登录控制器 * 实现电商系统用户登录生成 JWT Token */RestControllerRequestMapping(/user)publicclassLoginController{ResourceprivateUserServiceuserService;ResourceprivateJwtUtilsjwtUtils;/** * 用户登录接口 * param user 登录信息username、password * return 登录结果 Token */PostMapping(/login)publicResultMapString,Objectlogin(RequestBodyUseruser){// 1. 校验用户名密码非空if(user.getUsername()null||user.getPassword()null){returnResult.fail(用户名或密码不能为空);}// 2. 根据用户名查询用户LambdaQueryWrapperUserwrappernewLambdaQueryWrapper();wrapper.eq(User::getUsername,user.getUsername()).eq(User::getDeleted,0);UserexistUseruserService.getOne(wrapper);// 3. 用户不存在if(existUsernull){returnResult.fail(用户名不存在);}// 4. 密码校验实际项目用 BCrypt 加密此处用 MD5 演示StringinputPwdDigestUtils.md5DigestAsHex(user.getPassword().getBytes());if(!inputPwd.equals(existUser.getPassword())){returnResult.fail(密码错误);}// 5. 生成 JWT TokenStringtokenjwtUtils.generateToken(existUser.getId(),existUser.getUsername());// 6. 返回登录结果MapString,ObjectresultnewHashMap();result.put(token,token);result.put(user,existUser);returnResult.success(result);}}五、接口测试效果演示1. 登录请求请求POST /user/login请求体{username:zhangsan,password:123456}返回{code:200,msg:操作成功,data:{token:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...,user:{id:1,username:zhangsan,nickname:张三,status:1}}}2. 带 Token 请求用户接口请求头Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9…请求GET /user/1返回{code:200,msg:操作成功,data:{id:1,username:zhangsan,nickname:张三}}3. 无 Token / 过期 Token 请求返回{code:401,msg:未登录请先登录}六、高频踩坑总结新手必看坑 1跨域预检请求OPTIONS被拦截原因拦截器没有放行 OPTIONS 请求导致跨域失败解决方案在拦截器中添加 if (“OPTIONS”.equals(request.getMethod())) { return true; }直接放行预检请求坑 2Token 过期时间设置不合理原因过期时间太短用户频繁登录太长安全性低解决方案电商系统建议设置 7 天过期同时实现 Token 刷新机制后续可扩展坑 3密钥泄露Token 被篡改原因密钥过于简单生产环境硬编码在代码中解决方案密钥设置为 16 位以上复杂字符串生产环境通过配置中心管理禁止硬编码坑 4载荷存储敏感信息原因JWT 载荷是 Base64 编码可直接解码不能存储密码等敏感信息解决方案载荷仅存储用户 ID、用户名等非敏感信息敏感信息绝对不能存入坑 5拦截器放行路径配置错误原因登录、验证码等接口被拦截导致无法登录解决方案严格配置放行路径确保登录、注册、验证码等接口不受拦截七、总结与延伸本文完整实现了 SpringBoot 集成 JWT 实现登录认证 全局权限拦截完美适配电商管理系统的登录需求所有代码可直接复制到你的项目中使用。通过本文的实现你可以彻底解决前后端分离项目的登录认证问题实现无状态身份校验掌握 JWT 的核心原理与实战用法应对面试高频考点搭建企业级登录认证体系保障接口安全为后续权限控制RBAC、角色管理打下基础本文是电商管理系统实战系列的第 4 篇上一篇讲解了 MyBatis-Plus 条件查询避坑下一篇将讲解 SpringBoot 集成 Redis 实现缓存优化感兴趣的同学可以关注我持续更新 Java 后端实战内容。八、互动引导你在集成 JWT 时还遇到过哪些问题欢迎在评论区留言我会逐一解答觉得有用的同学点赞 收藏不迷路后续更新更多 Java 后端学习、项目实战、面试技巧关注我持续分享 Java 后端干货陪你从大二到秋招拿 offer

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

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

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…