双 Token 无感续登架构(前端标准落地)1)令牌设计AccessToken:短期(1h),业务接口鉴权;RefreshToken:滑动 7 天,仅用于刷新 AccessToken;2)自动
针对你提出的“双 Token 无感续登架构”我的回答是完全可以而且JWT是业界实现该架构的最佳实践方案。但需要特别注意的是RefreshToken 强烈建议存数据库Redis而 AccessToken 使用 JWT。这种“非对称存储”的组合才是生产环境的标准落地方式。以下是针对你需求的前端标准落地技术方案1. 令牌的具体JWT实现方案令牌存储方式载荷(Payload)核心字段过期策略AccessTokenJWT字符串不落库{ sub: userId, roles: [], exp: 1h }1小时无状态校验RefreshTokenJWT字符串 Redis缓存{ sub: userId, version: 123 }7天有状态校验存Redis为什么RefreshToken不纯粹用JWT因为JWT一旦签发在有效期内无法主动失效。如果用户修改密码或设备丢失旧的RefreshToken依然可用。将RefreshToken的jti唯一ID存入Redis并设置7天过期后端校验时先验JWT签名再查Redis是否存在且未失效这样就能实现“滑动续期”和“手动踢下线”。2. 前端无感续期的核心拦截器逻辑Axios示例前端只需关注401状态码和业务错误码如ERR_TOKEN_EXPIRED。核心是请求队列机制防止多个接口同时过期导致多次刷新。javascript// 刷新Token锁 let isRefreshing false; // 等待队列存储刷新期间失败的请求回调 let failedQueue []; const processQueue (error, token null) { failedQueue.forEach(prom { if (error) prom.reject(error); else prom.resolve(token); }); failedQueue []; }; // 响应拦截器 axios.interceptors.response.use( response response, async (error) { const { config, response } error; // 条件返回401 且 不是刷新接口本身 且 未重试过 if (response?.status 401 !config._retry) { // 防止重复刷新 if (isRefreshing) { return new Promise((resolve, reject) { failedQueue.push({ resolve, reject }); }).then(token { config.headers.Authorization Bearer ${token}; return axios(config); }).catch(err Promise.reject(err)); } config._retry true; isRefreshing true; const refreshToken localStorage.getItem(refresh_token); try { // 调用刷新接口携带 refreshToken通常放在Body或Header const res await axios.post(/auth/refresh, { refreshToken }); const { newAccessToken, newRefreshToken } res.data; // 更新本地存储 localStorage.setItem(access_token, newAccessToken); localStorage.setItem(refresh_token, newRefreshToken); // 更新等待队列中的请求头 processQueue(null, newAccessToken); // 重试当前失败的请求 config.headers.Authorization Bearer ${newAccessToken}; return axios(config); } catch (refreshError) { // RefreshToken彻底过期后端返回403跳转登录页 processQueue(refreshError, null); localStorage.clear(); window.location.href /login; return Promise.reject(refreshError); } finally { isRefreshing false; } } return Promise.reject(error); } );3. 刷新RefreshToken滑动的后端逻辑后端在刷新接口中不仅要生成新的AccessToken必须把新的RefreshToken也一起返回。java// 伪代码示例 public TokenPair refreshToken(String oldRefreshToken) { // 1. 校验旧RefreshToken的签名和Redis中是否存在 String jti parseJWT(oldRefreshToken).getId(); if (!redis.hasKey(refresh: jti)) { throw new ExpiredException(彻底过期); } // 2. 生成新的AccessToken1小时 String newAccess JWT.create().withExpiresAt(new Date(System.currentTimeMillis() 3600000)).sign(); // 3. **关键**生成全新的RefreshToken覆盖Redis中的旧值 String newRefresh JWT.create().withExpiresAt(new Date(System.currentTimeMillis() 7 * 24 * 3600000)).sign(); String newJti parseJWT(newRefresh).getId(); // 删除旧的Redis Key存入新的Key过期时间重置为7天 redis.delete(refresh: jti); redis.setex(refresh: newJti, 7 * 24 * 3600, userId); return new TokenPair(newAccess, newRefresh); }4. 为什么说这是“前端标准落地”内存与存储分离AccessToken放在内存或localStorage注意XSS风险推荐内存嗅探RefreshToken放在localStorage或httpOnly Cookie。并发控制通过isRefreshing锁和failedQueue队列确保100个接口同时401时只发起1次刷新请求极大节省服务器资源。静默续期用户在操作中途如果Token过期请求会被阻塞但界面无白屏刷新成功后请求自动重发用户完全无感知。⚠️ 特别提醒安全红线绝对不要在前端使用JWT解密RefreshToken来判断是否过期前端只负责携带和存储是否过期、是否滑动必须由后端根据Redis中的时间和版本来判断。前端拦截器只认HTTP状态码401/403。如果你需要我可以继续为你细化前端如何防止XSS窃取Token如使用内存存储Web Worker或者刷新Token接口的并发锁优化代码需要吗

相关新闻

ts-extras高级用法:objectMapValues与objectUpdate实现类型安全的对象操作

ts-extras高级用法:objectMapValues与objectUpdate实现类型安全的对象操作

ts-extras高级用法:objectMapValues与objectUpdate实现类型安全的对象操作 【免费下载链接】ts-extras Essential utilities for TypeScript projects 项目地址: https://gitcode.com/gh_mirrors/ts/ts-extras TypeScript开发者在处理对象操作时常常面临类型…

2026/7/17 15:53:02阅读更多 →
Bitfocus Companion:从零开始打造专业直播控制台的5步指南

Bitfocus Companion:从零开始打造专业直播控制台的5步指南

Bitfocus Companion:从零开始打造专业直播控制台的5步指南 【免费下载链接】companion Bitfocus Companion enables the Elgato Stream Deck and other controllers to be a professional shotbox surface for an increasing amount of different presentation swit…

2026/7/17 15:53:02阅读更多 →
计算机小程序毕设实战-宠物门店信息运维小程序的设计与实现 基于 SpringBoot + 微信小程序的宠物机构日常管理系统【完整源码+LW+部署说明+演示视频,全bao一条龙等】

计算机小程序毕设实战-宠物门店信息运维小程序的设计与实现 基于 SpringBoot + 微信小程序的宠物机构日常管理系统【完整源码+LW+部署说明+演示视频,全bao一条龙等】

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/7/17 15:42:37阅读更多 →
为什么Tabby是现代开发者必备的跨平台终端工具?终极使用指南

为什么Tabby是现代开发者必备的跨平台终端工具?终极使用指南

为什么Tabby是现代开发者必备的跨平台终端工具?终极使用指南 【免费下载链接】tabby A terminal for a more modern age 项目地址: https://gitcode.com/GitHub_Trending/ta/tabby 你是否经常需要在不同的终端工具之间切换?本地开发用Windows Ter…

2026/7/17 17:08:59阅读更多 →
【小程序课程设计/毕业设计】基于 Android 的同城休闲垂钓服务系统 钓友互动分享与预约垂钓平台的设计与实现【附源码、数据库、万字文档】

【小程序课程设计/毕业设计】基于 Android 的同城休闲垂钓服务系统 钓友互动分享与预约垂钓平台的设计与实现【附源码、数据库、万字文档】

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/7/17 17:08:59阅读更多 →
【小程序课程设计/毕业设计】基于 SpringBoot + 小程序的乡村就医服务管理系统 乡镇居民健康问诊预约服务小程序【附源码、数据库、万字文档】

【小程序课程设计/毕业设计】基于 SpringBoot + 小程序的乡村就医服务管理系统 乡镇居民健康问诊预约服务小程序【附源码、数据库、万字文档】

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/7/17 17:08:59阅读更多 →
GNSS与RTK的原理、应用

GNSS与RTK的原理、应用

GNSS与RTK的原理、应用第一章 GNSS基础知识1.1 卫星导航系统概述1.2 GNSS定位原理入门1.3 GNSS定位中的误差及分类1.4 差分定位技术的分类与应用第二章 经典RTK技术基础载波相位差分的数学模型模糊度的固定方法RTCM通信协议 和 Nrtip通信协议第三章 网络RTK技术基础网络RTK技术…

2026/7/17 17:08:59阅读更多 →
Midscene.js:视觉驱动的跨平台AI自动化框架技术革新

Midscene.js:视觉驱动的跨平台AI自动化框架技术革新

Midscene.js:视觉驱动的跨平台AI自动化框架技术革新 【免费下载链接】midscene AI-powered, vision-driven UI automation for every platform. 项目地址: https://gitcode.com/GitHub_Trending/mid/midscene Midscene.js是一款基于视觉语言模型的跨平台UI自…

2026/7/17 17:08:59阅读更多 →
DDE-GoCode代码实现原理:深入理解Golang依赖包的工作机制

DDE-GoCode代码实现原理:深入理解Golang依赖包的工作机制

DDE-GoCode代码实现原理:深入理解Golang依赖包的工作机制 【免费下载链接】DDE-GoCode dde desktop need some golang depend package 项目地址: https://gitcode.com/openeuler/DDE-GoCode 前往项目官网免费下载:https://ar.openeuler.org/ar/ …

2026/7/17 17:03:56阅读更多 →
VSCode TypeScript 环境配置对比:全局安装 vs 项目本地安装的4个关键差异

VSCode TypeScript 环境配置对比:全局安装 vs 项目本地安装的4个关键差异

VSCode TypeScript 环境配置对比:全局安装 vs 项目本地安装的4个关键差异当你在VSCode中启动一个新的TypeScript项目时,第一个技术决策往往从安装方式开始。这个看似简单的选择——全局安装还是项目本地安装——实际上会深刻影响你的开发流程、团队协作和…

2026/7/17 10:42:55阅读更多 →
智慧树刷课插件:5分钟实现自动化学习的智能助手

智慧树刷课插件:5分钟实现自动化学习的智能助手

智慧树刷课插件:5分钟实现自动化学习的智能助手 【免费下载链接】zhihuishu 智慧树刷课插件,自动播放下一集、1.5倍速度、无声 项目地址: https://gitcode.com/gh_mirrors/zh/zhihuishu 智慧树刷课插件是一款专为智慧树在线教育平台设计的Chrome浏…

2026/7/17 8:31:03阅读更多 →
Steam创意工坊下载器WorkshopDL:跨平台游戏模组获取的终极解决方案

Steam创意工坊下载器WorkshopDL:跨平台游戏模组获取的终极解决方案

Steam创意工坊下载器WorkshopDL:跨平台游戏模组获取的终极解决方案 【免费下载链接】WorkshopDL WorkshopDL - The Best Steam Workshop Downloader 项目地址: https://gitcode.com/gh_mirrors/wo/WorkshopDL 你是否在GOG或Epic Games Store购买了心仪的游戏…

2026/7/17 13:22:23阅读更多 →
VS Code 高效配置与个性化定制全攻略

VS Code 高效配置与个性化定制全攻略

1. VS Code 高效配置基础作为一款轻量级但功能强大的代码编辑器,VS Code 的默认配置已经能满足基本需求,但通过合理调整设置可以大幅提升编码效率。我使用 VS Code 已经有五年多时间,期间尝试过各种配置方案,总结出这套适合大多数…

2026/7/17 0:00:01阅读更多 →
从竞赛代码到桌面工具:让 SuperADD 与 SubspaceAD 真正跑进自己的图像

从竞赛代码到桌面工具:让 SuperADD 与 SubspaceAD 真正跑进自己的图像

在异常检测领域,很多优秀算法最初都是以研究代码的形式发布的。它们能够在固定测试集上复现实验结果,却不一定能被普通用户直接拿来测试自己的图片。尤其是最近很多算法仅提供在固定测试集的测试环境,而gradio的demo演示也不会提供。 对工程应用和在自己的图片上进行测试来…

2026/7/17 0:00:01阅读更多 →
WinRAR高效配置指南:从基础安装到高级压缩实战

WinRAR高效配置指南:从基础安装到高级压缩实战

前几天帮同事处理一个客户发来的压缩包,解压时系统自带的工具弹出一串乱码,换用 WinRAR 却顺利打开了。这种看似简单的场景,恰恰暴露了不同压缩工具在处理非标准编码、分卷压缩或加密文件时的差异。WinRAR 作为一款老牌工具,真正价…

2026/7/17 0:00:01阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/16 20:13:14阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/17 13:22:38阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/16 17:10:26阅读更多 →