简介这份源码资源面向使用若依框架进行企业级开发的工程师聚焦于token过期时间的配置调整问题。若依作为轻量级快速开发平台默认token有效期为30分钟在部分业务场景下需要延长会话时长资源给出了前后端一致修改的完整参考。压缩包共6个文件约7KB包含后端application.yml、前端request.js、index.html、README.md及.gitignore、.inscode等配置与说明文件分别对应后端过期参数、前端axios超时设置及项目基础配置。已有196人学习下载。读者可据此掌握将后端expireTime调整为120分钟、前端timeout同步设为7200000毫秒的具体写法理解前后端过期时间保持一致对避免访问中断的意义并延伸了解refresh token刷新机制与密码策略、多因素认证等安全措施的配合思路适合需要快速落地会话控制调整的开发者参考。1. 若依框架 token 过期设置从 30 分钟默认值到自定义续期策略很多用若依RuoYi做后台系统的开发者第一次被业务方追问「为什么用户挂着页面半小时就被踢出去」时才意识到 token 过期这件事不是改个数字那么简单。若依默认把 token 有效期设成 30 分钟且采用「固定过期」策略——时间一到无论用户是否还在操作一律失效。这在演示环境没问题一旦上线到需要长时间填表单、传大文件、做审批流的场景就会变成高频投诉点。这篇笔记围绕若依框架 token 过期设置展开把源码里几个关键位置、配置项含义、续期逻辑改造、以及我踩过的坑一次讲清楚。适合正在用若依做二次开发、需要自定义登录态时长的后端同学也适合想搞懂 JWT Redis 双存储这套机制的人。2. 若依 token 机制拆解为什么过期时间藏在三个地方2.1 从登录接口追到 TokenService若依的登录态不是纯 JWT 自包含而是「JWT 携带一个 uuid Redis 存完整用户信息」的混合模式。这个设计决定了过期时间不止一处配置。先看登录入口SysLoginService.login校验完账号密码后调用tokenService.createToken(loginUser)。真正决定过期的是TokenService里的两个字段expireTimeRedis 键的过期秒数和 JWT 自身的EXPIRE_TIME分钟。很多人只改了application.yml里的token.expireTime结果发现前端还是半小时掉线就是因为 JWT 那层没同步。// TokenService.java 关键片段若依 4.x 常见结构 public class TokenService { // 刷新阈值剩余有效期低于 20 分钟时才续期避免每次请求都写 Redis private static final long MILLIS_MINUTE_TEN 20 * 60 * 1000L; // JWT 自身过期时间单位分钟默认 30 private static final long EXPIRE_TIME 30; public String createToken(LoginUser loginUser) { String token IdUtils.fastUUID(); loginUser.setToken(token); setUserAgent(loginUser); refreshToken(loginUser); // 写入 Redis并设置 expireTime MapString, Object claims new HashMap(); claims.put(Constants.LOGIN_USER_KEY, token); return createToken(claims); } private String createToken(MapString, Object claims) { return Jwts.builder() .setClaims(claims) .signWith(SignatureAlgorithm.HS512, secret) .setExpiration(new Date(System.currentTimeMillis() EXPIRE_TIME * 60 * 1000)) .compact(); } }逻辑说明createToken先生成一个 uuid 作为 Redis 的 key 后缀把用户对象序列化存进 Redis 并设置过期时间再用同一个 uuid 作为 JWT 的 claim 签发 token。请求进来时过滤器解析 JWT 拿到 uuid去 Redis 查用户信息。所以真正的「登录态存活」由 Redis 决定JWT 的expiration只是第一道闸。参数上EXPIRE_TIME是硬编码常量expireTime来自配置文件两者必须一起改否则会出现「Redis 还有数据但 JWT 已过期」的 401。2.2 application.yml 里的 token 配置项逐个说若依把可配置项集中在application.yml的token节点下常见字段如下表。注意不同小版本字段名略有差异以你本地源码为准。配置项含义默认值调整建议token.header前端携带 token 的请求头名Authorization一般不动token.secretJWT 签名密钥固定字符串上线必须换长度够token.expireTimeRedis 中登录态过期秒数30按业务设 1800~7200token.autoRefresh是否开启自动续期部分版本无有则设 trueexpireTime单位是分钟不是秒这点坑过不少人——写成 3600 以为是 1 小时实际是 60 小时。改完配置后TokenService里通过Value(${token.expireTime})注入再乘以 60 转成秒传给 Redis。如果你发现改了没生效先确认注入的字段有没有被static修饰静态字段无法被Value注入这是很隐蔽的一个翻车点。2.3 过滤器如何校验过期并触发续期请求进入后JwtAuthenticationTokenFilter会拦截并调用tokenService.getLoginUser(request)。这个方法内部先解析 JWT再从 Redis 取LoginUser取到后调用verifyToken(loginUser)判断是否需要续期。public void verifyToken(LoginUser loginUser) { long expireTime loginUser.getExpireTime(); long currentTime System.currentTimeMillis(); // 剩余时间不足 20 分钟自动刷新 if (expireTime - currentTime MILLIS_MINUTE_TEN) { refreshToken(loginUser); } }逻辑说明expireTime是上次写入 Redis 时算出的绝对过期时间戳。每次请求如果发现剩余不足 20 分钟就重新refreshToken把 Redis 过期时间往后推同时更新loginUser里的expireTime。这就是「滑动过期」的雏形。参数MILLIS_MINUTE_TEN控制续期触发点设太小会导致频繁写 Redis设太大则续期不及时。我一般把它设成总有效期的三分之一左右比如总时长 2 小时就设 40 分钟。3. 改 token 过期时间三种改法与对应源码位置3.1 只改配置文件的快速改法最省事的做法是只动application.yml适合过期时间需求固定、不要求滑动续期的场景。# application.yml token: header: Authorization secret: your-own-secret-key-please-change expireTime: 120 # 单位分钟这里表示 2 小时改完后重启服务。但要注意JWT 那层的EXPIRE_TIME常量如果还是 30就会出现「Redis 里登录态 2 小时但 JWT 30 分钟就过期」的矛盾。所以快速改法必须同步把TokenService.EXPIRE_TIME改成 120。两处一致才不会出现中途 401。这个改法简单代价是用户 2 小时一到还是会被强制退出没有续期。3.2 开启滑动续期让活跃用户不掉线要让「用户一直在操作就不掉线」得依赖verifyToken的续期逻辑。确认你的版本里过滤器调用了它。如果没有需要手动在getLoginUser里补上。public LoginUser getLoginUser(HttpServletRequest request) { String token getToken(request); if (StringUtils.isNotEmpty(token)) { Claims claims parseToken(token); String uuid (String) claims.get(Constants.LOGIN_USER_KEY); String userKey getTokenKey(uuid); LoginUser loginUser redisCache.getCacheObject(userKey); if (loginUser ! null) { verifyToken(loginUser); // 关键触发续期判断 } return loginUser; } return null; }逻辑说明每次请求都走一遍verifyToken剩余时间不足阈值就刷新 Redis 过期时间。这样活跃用户的登录态会一直延续只有连续不操作超过总时长才会失效。参数上续期阈值和总时长要配合总时长 2 小时、阈值 40 分钟意味着用户只要 40 分钟内有一次请求就不会掉线。如果业务要求「绝对不超过 8 小时」还得额外加一个首次登录时间戳做硬上限否则滑动续期会让登录态无限延长。3.3 自定义过期策略按角色区分时长后台系统常有「管理员短、普通用户长」或「移动端长、Web 端短」的需求。这时固定配置不够用需要在createToken里按用户属性动态设置。public String createToken(LoginUser loginUser) { String token IdUtils.fastUUID(); loginUser.setToken(token); setUserAgent(loginUser); // 按角色动态计算过期分钟数 long minutes 30; if (loginUser.getUser().isAdmin()) { minutes 15; // 管理员敏感短一点 } else if (isMobile(loginUser)) { minutes 7 * 24 * 60; // 移动端 7 天 } loginUser.setExpireTime(System.currentTimeMillis() minutes * 60 * 1000); redisCache.setCacheObject(getTokenKey(token), loginUser, (int) minutes, TimeUnit.MINUTES); return createToken(Collections.singletonMap(Constants.LOGIN_USER_KEY, token), minutes); }逻辑说明把过期分钟数抽成变量按角色或终端类型分支计算再分别写入LoginUser.expireTime、Redis 过期时间和 JWT 的setExpiration。三处必须用同一个minutes否则又会出现不一致。参数上移动端设长是因为 App 频繁切后台短时长体验差管理员设短是安全考虑。这里isMobile可以读请求头 User-Agent也可以让前端登录时多传一个终端标识字段。4. 避坑与排查token 过期设置里最容易翻车的 5 个点4.1 改了 expireTime 却不生效现象配置文件改成 120重启后用户还是 30 分钟掉线。原因通常是TokenService里注入expireTime的字段被static修饰Spring 无法给静态字段注入值实际用的还是默认或旧值。解决去掉static或者改用PostConstruct手动赋值。排查时在createToken里打一行日志输出实际分钟数一眼就能看出用的是哪个值。4.2 Redis 有数据但接口返回 401现象Redis 里明明能查到登录态请求却提示认证失败。原因是 JWT 自身的EXPIRE_TIME比 Redis 短JWT 先过期parseToken直接抛异常根本走不到查 Redis 那步。解决保证 JWT 过期时间大于等于 Redis 过期时间。我一般让 JWT 比 Redis 多留 5 分钟缓冲避免边界时刻的玄学问题。4.3 续期导致登录态无限延长现象开了滑动续期后用户只要不关页面就永远不掉线安全审计过不了。原因是verifyToken只往后推时间没有绝对上限。解决在LoginUser里加一个loginTime首次登录时间戳续期前判断currentTime - loginTime是否超过硬上限比如 12 小时超过就拒绝续期强制重新登录。4.4 多节点部署下续期不同步现象集群部署时用户请求打到 A 节点续了期打到 B 节点却提示过期。原因是各节点本地缓存或时间不同步。若依默认用 Redis 存登录态本身是共享的但如果你的版本里加了本地缓存层就会出现不一致。解决续期只写 Redis不写本地缓存同时确保各节点服务器时间用 NTP 对齐时间偏差超过续期阈值就会出问题。4.5 前端没处理 token 过期后的跳转现象后端返回 401前端页面卡死或白屏用户不知道发生了什么。原因是前端拦截器只处理了业务错误码没处理 401。解决在前端请求拦截器里判断响应码401 时清除本地 token 并跳登录页。若依前端一般在request.js里已有处理但如果你自定义了过期返回码记得同步改前端判断逻辑否则后端改得再对用户体验还是断的。5. 进阶技巧用配置中心动态调整 token 时长前面几种改法都要重启服务生产环境频繁重启不现实。更稳的做法是把 token 过期时间抽到配置中心如 Nacos配合RefreshScope实现热更新。核心思路是让TokenService从一个可刷新的配置 Bean 里读时长而不是读启动时固定的Value。Component RefreshScope public class TokenProperties { // 从配置中心读取支持不重启刷新 Value(${token.expireTime:120}) private long expireTime; Value(${token.refreshThreshold:40}) private long refreshThreshold; public long getExpireMillis() { return expireTime * 60 * 1000; } public long getThresholdMillis() { return refreshThreshold * 60 * 1000; } }逻辑说明RefreshScope让这个 Bean 在配置中心推送新值后被重建TokenService每次调用getExpireMillis()拿到的都是最新值。这样运营侧发现某类用户掉线频繁改个配置推送即可不用发版。参数上refreshThreshold建议设成expireTime的三分之一两者都放配置中心方便联动调整。验证是否生效可以写一个简单的检查方法登录后连续发请求观察 Redis 里 key 的 TTL 是否在接近阈值时被重置。用redis-cli执行TTL 登录key如果每次请求后 TTL 都回到接近总时长说明续期生效如果 TTL 一直递减到 0说明续期没触发回去检查verifyToken有没有被调用。我自己的习惯是任何涉及登录态的改动上线前必做三件事确认三处时间一致、确认续期阈值合理、确认前端 401 处理正常。这三件做完token 过期相关的投诉基本就清零了。希望帮到你。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?