李锋镝的博客

  • 首页
  • 时间轴
  • 说说
  • 系列文章
  • AI工具集
  • 论坛
  • 左邻右舍
    • 左邻右舍
    • 朋友圈
    • 游客中心
  • 留言
    • 留言
    • 走心评论
  • 关于
    • 关于本站
    • Now
    • 每日心情
    • 网站地图
    • 网站统计
    • 赞助
  • 星球穿梭
  • 🚇开往
白雪成红
惟坚韧者始能遂其志
  1. 首页
  2. 原创
  3. 正文

双 Token 机制

2025年5月19日 约 875 字3 分钟 272 0 4
本文最后更新于 2025年5月19日,距今已 509 天,其中的信息可能已经发生变化,请注意甄别。

一、什么是双 Token 机制?

双Token机制是通过两种令牌管理用户认证与授权的方案,核心令牌包括:

  • Access Token(访问令牌)
    • 用于身份验证和授权,每次请求时携带。
    • 有效期短(如15分钟),降低泄漏风险。
  • Refresh Token(刷新令牌)
    • 用于在Access Token过期后获取新令牌。
    • 有效期长(如7天),支持无缝续期。

二、JWT 与双 Token 机制的关系

1. JWT的结构

JWT是双Token机制中Access Token的常用格式,由三部分组成:

  • Header(头部):指定令牌类型(JWT)和签名算法(如HMAC SHA256)。
  • Payload(负载):包含用户标识(sub)、过期时间(exp)、权限等声明。
  • Signature(签名):使用密钥对头部和负载签名,验证数据完整性。

2. 双Token的分工

  • Access Token:采用JWT格式,携带用户认证信息。
  • Refresh Token:独立令牌,用于刷新Access Token,通常存储于安全位置。

三、双 Token 的工作流程

  1. 用户登录

    • 用户提交用户名/密码,服务器验证通过后返回Access Token(短时效)和Refresh Token(长时效)。
  2. 正常访问流程

    • 客户端在请求头中携带Access Token(如Authorization: Bearer <token>)。
    • 服务器验证Access Token有效后,返回请求资源。
  3. Access Token过期

    • 客户端检测到Access Token过期,向服务器发送Refresh Token。
    • 服务器验证Refresh Token有效,生成新的Access Token并返回。
  4. Refresh Token过期

    • 若Refresh Token失效,用户需重新登录以获取新的双Token。

四、双 Token 机制的优势

1. 提高安全性

  • Access Token存储:存于内存(如JavaScript变量),页面刷新即清空,减少持久化泄漏风险。
  • Refresh Token存储:通过HttpOnly Cookie存储,防止XSS攻击窃取令牌。

2. 无缝用户体验

  • 自动刷新Access Token,避免频繁登录,适合长会话场景(如电商、社交应用)。

3. 无状态认证

  • JWT自身携带用户信息,服务器无需存储会话状态,仅需验证Refresh Token(可选存储于数据库)。

五、如何实现双 Token 机制?

1. 生成令牌(代码示例)

const jwt = require('jsonwebtoken');

// 生成Access Token(15分钟过期)
function generateAccessToken(user) {
  return jwt.sign(
    { sub: user.id, role: user.role }, // 负载信息
    'access_secret_key', // 签名密钥
    { expiresIn: '15m' }
  );
}

// 生成Refresh Token(7天过期)
function generateRefreshToken(user) {
  return jwt.sign(
    { sub: user.id }, // 简化负载(仅需用户标识)
    'refresh_secret_key',
    { expiresIn: '7d' }
  );
}

2. 存储Refresh Token

  • 服务器端:存入数据库,关联用户ID(适合高安全场景)。
  • 客户端:通过HttpOnly Cookie存储(需配合Secure属性,避免明文传输)。

3. 验证Access Token

function verifyAccessToken(req, res, next) {
  const token = req.headers.authorization?.split(' ')[1]; // 解析Bearer Token
  if (!token) return res.status(401).json({ message: '缺少访问令牌' });

  jwt.verify(token, 'access_secret_key', (err, decoded) => {
    if (err) return res.status(403).json({ message: '令牌无效或过期' });
    req.user = decoded; // 将用户信息附加到请求对象
    next(); // 继续处理请求
  });
}

4. 刷新Access Token

function refreshTokenHandler(req, res) {
  const refreshToken = req.body.refreshToken; // 从请求体获取Refresh Token

  // 验证Refresh Token
  jwt.verify(refreshToken, 'refresh_secret_key', (err, user) => {
    if (err) return res.status(403).json({ message: '刷新令牌无效' });

    // 生成新的Access Token
    const newAccessToken = generateAccessToken(user);
    res.json({ accessToken: newAccessToken });
  });
}
本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可
分享到

双 Token 机制

也可使用浏览器菜单中的「分享」功能

微信扫一扫分享

标签: JAVA JWT SSO Token 登录
最后更新:2025年5月19日

岁月同一天 10 月 11 日

回望过去的今天,你在写什么

  • 中间件
    1 年前 2025年10月11日
    Kafka 为什么要抛弃 Zookeeper?

    Kafka 抛弃 Zookeeper(引入 KRaft 模式)是为了解决长期依赖 Zookeeper 带来的性能瓶颈、架…

  • 中间件
    1 年前 2025年10月11日
    高性能场景为什么推荐使用PostgreSQL,而非MySQL?

    在高性能场景(如高并发读写、复杂查询、大数据量存储、多维度数据处理等)中,PostgreSQL 常被优先推荐,核心原因在…

  • 原创
    7 年前 2019年10月11日
    JAVA关键字之volatile关键字说明

    volatile作用 volatile主要是为了解决多线程内存不可见问题。 对于一写多读,是可以解决变量同步问题,但是如…

相关文章
  • JAVA线程池简析(JDK1.6)2019年6月13日
  • ThreadPoolExecutor如何实现线程复用及超时销毁2021年6月18日
  • Java浮点数运算2022年7月15日
  • ZGC介绍2025年2月15日
  • 配置Jackson使用字段而不是getter/setter来序列化和反序列化2026年3月19日

李锋镝

既然选择了远方,便只顾风雨兼程。

打赏 点赞
< 上一篇
下一篇 >
1234567891112131415161718192021222324252627282930313233343536373839404142434446474849505152535455575859606162636465666769727476777879808182858687909293949596979899
取消回复
…

文章评论

  • GoodBoyboyLv 2

    然而令我难蚌的是,我们学校找人开发的应用,accessToken有效期超长(几个月),refreshToken没用,而且在post请求中将jwt放在url路径中,我都懒得喷了

    WindowsWindowsFirefox 131.0Firefox 131.0中国中国-湖南-长沙
    2025年6月23日
    00 回复
    • 李锋镝博主

      @GoodBoyboy 哈哈

      macOSmacOSChrome 137.0.0.0Chrome 137.0.0.0中国中国-北京
      2025年6月24日
      00 回复
    • duzhuoLv 1

      @GoodBoyboy 哈哈 兄弟那我看眼日志你不炸了吗

      LinuxLinuxChrome 138.0.0.0Chrome 138.0.0.0中国中国-湖北-武汉
      2025年7月24日
      00 回复
      • GoodBoyboyLv 2

        @duzhuo 世界就是一个巨大的草台班子

        WindowsWindowsFirefox 131.0Firefox 131.0中国中国-湖南-长沙
        2025年7月25日
        00 回复
  • 土狗跟随主人出去遛街,看到一只外国狗一身长长的白毛。
    土狗说:“人家真有钱,穿着长袍,戴着项链,主人还牵着逛街。”
    另一只土狗听到了说:“它被人包养了,我们是被人雇佣。”

    听点儿音乐吧 朋友~
    文章目录
    最新 热点 随机
    最新 热点 随机
    讨论下XXL-JOB GLUE模式的安全问题 心气没了,干什么都不得劲 Kratos-plus v1.1.26版本更新说明 我觉得是时候公布我的导航网站了 代码是 AI 写的,生产事故谁背锅? 给主题增加了游客中心功能
    给主题增加了游客中心功能我觉得是时候公布我的导航网站了游本昌去世关于主题加载速度优化的一点儿小演进给主题增加了Now、每日心情、年度回顾、岁月同一天、随机漫步等功能心气没了,干什么都不得劲
    如何在面试中介绍自己的项目经验 写了个日期进度条的小插件 Java中的字符和字符串 C# 11 的这个新特性,我愿称之最强! 从入门到精通:Ollama 本地大模型全攻略(含 UI 界面、多语言调用、进阶优化) JAVA线程池简析(JDK1.6)
    最近评论
    老张博客 发布于 10 小时前(10月10日) NAS现在就不要搞了吧,除非你手里有内存和硬盘。
    李锋镝 发布于 15 小时前(10月10日) 确实,很多不必要的东西,买了回来也是吃灰……
    林羽凡 发布于 18 小时前(10月10日) 一个是不想折腾了,另一个有些觉得没必要的折腾或购买,想想就会算了。
    李锋镝 发布于 18 小时前(10月10日) 少年老成吧大概是 :21:
    Hary 发布于 19 小时前(10月10日) 我也是这样,感觉都不想折腾了,我还没到中年呢吧啊啊啊
    标签聚合
    K8s WordPress IDEA 架构 AI 分布式 AI编程 Redis Claude 数据库 ElasticSearch Spring 多线程 SpringBoot Theme 日常 SQL MySQL JVM JAVA
    友情链接
    • 韩情脉脉
    • 哥斯拉
    • 志文工作室
    • 九仞之行
    • lijie blog
    • 彬红茶日记
    • 知向前端
    • 瓦匠个人小站
    • Serendipity
    • 搬砖日记
    • Mr.Sun的博客
    • 老张博客
    • 懋和道人
    • 林羽凡
    • Honesty
    • 皮皮社
    • sssr7844的博客
    • 韩小韩博客

    COPYRIGHT © 2016-2026 lifengdi.com. ALL RIGHTS RESERVED.

    lifengdi.com 十年之约虫洞

    Domain age badge for lifengdi.com

    Theme Kratos-plus By Dylan Li

    津ICP备2024022503号-3

    京公网安备11011502039375号