您当前的位置:首页 > 电脑百科 > 程序开发 > 编程百科

无感知刷新Token

时间:2023-04-04 12:13:45  来源:今日头条  作者:Chadwik

引言

在前后端分离的应用中,使用Token进行认证是一种较为常见的方式。但是,由于Token的有效期限制,需要不断刷新Token,否则会导致用户认证失败。为了解决这个问题,可以实现无感知刷新Token的功能,本文将介绍如何实现无感知刷新Token。

Token认证的原理

在Web应用中,常见的Token认证方式有基于Cookie和基于Token的认证。基于Cookie的认证方式是将认证信息保存在Cookie中,每次请求时将Cookie发送给服务器进行认证;而基于Token的认证方式是将认证信息保存在Token中,每次请求时将Token发送给服务器进行认证。

在基于Token的认证方式中,客户端将认证信息保存在Token中,而不是保存在Cookie中。在认证成功后,服务器将生成一个Access Token和一个Refresh Token,并将它们返回给客户端。Access Token用于访问受保护的API,Refresh Token用于获取新的Access Token。

什么是无感知刷新Token

无感知刷新Token是指,在Token过期之前,系统自动使用Refresh Token获取新的Access Token,从而实现Token的无感知刷新,用户可以无缝继续使用应用。

在实现无感知刷新Token的过程中,需要考虑以下几个方面:

  • 如何判断Token是否过期?
  • 如何在Token过期时自动使用Refresh Token获取新的Access Token?
  • 如何处理Refresh Token的安全问题?

下面将介绍如何实现无感知刷新Token的具体步骤。

实现步骤

步骤一:获取Access Token和Refresh Token

在认证成功后,需要将Access Token和Refresh Token发送给客户端。Access Token用于访问受保护的API,Refresh Token用于获取新的Access Token。可以使用JWT(jsON Web Token)或OAuth2(开放授权)等方式实现认证。

在JWT中,可以使用如下代码生成Access Token和Refresh Token:

  1. const accessToken = jwt.sign({userId: '123'}, 'ACCESS_TOKEN_SECRET', {expiresIn: '15m'});
  2. const refreshToken = jwt.sign({userId: '123'}, 'REFRESH_TOKEN_SECRET', {expiresIn: '7d'});

步骤二:在请求中携带Access Token

在每个需要认证的API请求中,需要在请求头中携带Access Token,如下所示:

  1. GET /api/user HTTP/1.1
  2. Host: example.com
  3. Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

在前端中,可以使用AxIOS等库设置请求头:

  1. axios.defaults.headers.common['Authorization'] = `Bearer ${accessToken}`;

步骤三:拦截401 Unauthorized响应

在服务器返回401 Unauthorized响应时,说明Access Token已经过期,需要使用Refresh Token获取新的Access Token。可以使用Axios拦截器或Fetch API的中间件实现拦截。

在Axios中,可以使用如下代码实现拦截器:

  1. axios.interceptors.response.use(response => {
  2. return response;
  3. }, error => {
  4. const originalRequest = error.config;
  5. if (error.response.status === 401 && !originalRequest._retry) {
  6. originalRequest._retry = true; //防止无限调用
  7. return axios.post('/api/refresh_token', {refreshToken})
  8. .then(response => {
  9. const { access_token, refresh_token } = response.data;
  10. localStorage.setItem('access_token', access_token);
  11. localStorage.setItem('refresh_token', refresh_token);
  12. axios.defaults.headers.common['Authorization'] = `Bearer ${access_token}`;
  13. originalRequest.headers.Authorization = `Bearer ${access_token}`;
  14. return axios(originalRequest);
  15. });
  16. }
  17. return Promise.reject(error);
  18. });

在Fetch中,可以使用如下代码实现中间件:

  1. function authMiddleware(request) {
  2. const access_token = localStorage.getItem('access_token');
  3. if (access_token) {
  4. request.headers.set('Authorization', `Bearer ${access_token}`);
  5. }
  6. return request;
  7. }
  8. function tokenRefreshMiddleware(response) {
  9. if (response.status === 401) {
  10. const refreshToken = localStorage.getItem('refresh_token');
  11. return fetch('/api/refresh_token', {
  12. method: 'POST',
  13. headers: {
  14. 'Content-Type': 'Application/json'
  15. },
  16. body: JSON.stringify({ refreshToken })
  17. }).then(response => {
  18. if (response.ok) {
  19. return response.json();
  20. }
  21. throw new Error('Refresh Token fAIled');
  22. }).then(data => {
  23. localStorage.setItem('access_token', data.access_token);
  24. localStorage.setItem('refresh_token', data.refresh_token);
  25. return Promise.resolve('refreshed');
  26. }).catch(error => {
  27. localStorage.removeItem('access_token');
  28. localStorage.removeItem('refresh_token');
  29. return Promise.reject(error);
  30. });
  31. }
  32. return Promise.resolve('ok');
  33. }
  34. fetch('/api/user', {
  35. method: 'GET',
  36. headers: {
  37. 'Content-Type': 'application/json'
  38. },
  39. middleware: [authMiddleware, tokenRefreshMiddleware]
  40. }).then(response => {
  41. console.log(response);
  42. }).catch(error => {
  43. console.error(error);
  44. });

在上述代码中,使用Axios或Fetch拦截器拦截401 Unauthorized响应,如果发现Access Token已经过期,则发送Refresh Token请求获取新的Access Token,并将新的Access Token设置到请求头中,重新发送请求。

步骤四:服务器处理Refresh Token请求

在服务器端,需要编写API处理Refresh Token请求,生成新的Access Token,并返回给客户端。

在JWT中,可以使用如下代码生成新的Access Token:

  1. const accessToken = jwt.sign({userId: '123'}, 'ACCESS_TOKEN_SECRET', {expiresIn: '15m'});

在刷新Token时,需要验证Refresh Token的合法性,可以使用如下代码验证Refresh Token:

  1. try {
  2. const payload = jwt.verify(refreshToken, 'REFRESH_TOKEN_SECRET');
  3. const accessToken = jwt.sign({userId: payload.userId}, 'ACCESS_TOKEN_SECRET', {expiresIn: '15m'});
  4. const refreshToken = jwt.sign({userId: payload.userId}, 'REFRESH_TOKEN_SECRET', {expiresIn: '7d'});
  5. res.json({access_token: accessToken, refresh_token: refreshToken});
  6. } catch (err) {
  7. res.sendStatus(401);
  8. }

在上述代码中,使用JWT的verify方法验证Refresh Token的合法性,如果验证成功,则生成新的Access Token和Refresh Token,并返回给客户端。

步骤五:设置定时刷新Token

为了避免Access Token过期时间太长,可以设置定时刷新Token的功能。可以使用定时器或Web Workers等方式实现定时刷新Token。在每次刷新Token时,需要重新获取新的Access Token和Refresh Token,并保存到客户端。

  1. function refreshToken() {
  2. const refreshToken = localStorage.getItem('refresh_token');
  3. axios.post('/api/refresh_token', {refreshToken})
  4. .then(response => {
  5. const { access_token, refresh_token } = response.data;
  6. localStorage.setItem('access_token', access_token);
  7. localStorage.setItem('refresh_token', refresh_token);
  8. axios.defaults.headers.common['Authorization'] = `Bearer ${access_token}`;
  9. })
  10. .catch(error => {
  11. console.error(error);
  12. });
  13. }
  14. setInterval(refreshToken, 14 * 60 * 1000); // 每14分钟刷新Token

在上述代码中,使用定时器每14分钟刷新Token。在刷新Token成功后,将新的Access Token和Refresh Token保存到客户端,并将新的Access Token设置到请求头中。

安全性考虑

在实现无感知刷新Token的过程中,需要考虑到Refresh Token的安全性问题。因为Refresh Token具有长期的有效期限,一旦Refresh Token被泄露,攻击者就可以使用Refresh Token获取新的Access Token,从而绕过认证机制,访问受保护的API。

为了增加Refresh Token的安全性,可以考虑以下几种措施:

  • 将Refresh Token保存在HttpOnly Cookie中,可以避免在客户端被JAVAScript获取;
  • 对Refresh Token进行加密或签名,可以增加其安全性。
  • 将Refresh Token保存在后端,前端通过接口和后端交互,实现刷新Access Token。


Tags:Token   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
训出GPT-5短缺20万亿token!OpenAI被曝计划建「数据市场」
全网真的无数据可用了!外媒报道称,OpenAl、Anthropic等公司正在努力寻找足够的信息,来训练下一代人工智能模型。前几天,OpenAI和微软被曝出正在联手打造超算「星际之门」,解决算...【详细内容】
2024-04-08  Search: Token  点击:(2)  评论:(0)  加入收藏
如何使用免费网络安全工具Canary Tokens查明黑客何时访问了您的文件?
译者 | 布加迪审校 | 重楼担心您的个人文件被黑客窃取吗?Canary Tokens是一款免费且易于使用的工具,可以快速部署。如果黑客打开您的文件,它就会通知您。什么是Canary Tokens?Ca...【详细内容】
2024-03-26  Search: Token  点击:(13)  评论:(0)  加入收藏
不依赖token,字节级模型来了!直接处理二进制数据
不依赖token,字节级模型来了!直接处理二进制数据来源:华尔街见闻 量子位bGPT显著提高了处理大规模数字数据序列的效率和可扩展性。最新GPT,不预测token了。微软亚研院等发布bGPT...【详细内容】
2024-03-12  Search: Token  点击:(14)  评论:(0)  加入收藏
关于“Cookie、Session、Token”彻底懂了
Cookie、Session、token的发展历程随着互联网的发展,身份验证和用户管理变得愈发重要,而Cookie、Session和Token便是这一领域发展的关键里程碑。综合而言,这三者的发展历程既是...【详细内容】
2023-12-11  Search: Token  点击:(189)  评论:(0)  加入收藏
jwt与token+redis,哪种方案更好用?
在选择 JWT 与 Token+Redis 时,系统的具体需求和设计目标将是决定性因素。这两种方案都有各自的优缺点,适用于不同的场景。JWT 方案: 优点:无状态性:后端不需要存储 Token,减轻了...【详细内容】
2023-12-03  Search: Token  点击:(21)  评论:(0)  加入收藏
解读大模型(LLM)的token
当人们谈论大型语言模型的大小时,参数会让我们了解神经网络的结构有多复杂,而token的大小会让我们知道有多少数据用于训练参数。正像陆奇博士所说的那样,大型语言模型为从文本...【详细内容】
2023-10-06  Search: Token  点击:(403)  评论:(0)  加入收藏
只有理解Token和内存,才能更好掌握ChatGPT!
作者 | Rusell Kohn编译 | 言征 ChatGPT 等大型语言模型 (LLM) 已经改变了 AI 格局,了解其复杂性对于充分发挥其潜力至关重要。这篇短文将重点讨论大语言模型中的Token限制和...【详细内容】
2023-08-21  Search: Token  点击:(288)  评论:(0)  加入收藏
碾压LLaMA,「猎鹰」彻底开源!400亿参数,万亿token训练,霸榜Hugging Face
新智元报道编辑:润 拉燕【新智元导读】来自阿联酋的免费商用开源大模型登顶Hagging Face排行榜,AI大模型创业者的春天就这样到来了。大模型时代,什么最重要?LeCun曾经给出的答案...【详细内容】
2023-06-02  Search: Token  点击:(99)  评论:(0)  加入收藏
将26个token压缩成1个,新方法极致节省ChatGPT输入框空间
进入正文之前,先考虑一下像 ChatGPT 这样的 Transformer 语言模型(LM)的 prompt: 随着每天产生数百万用户和查询,ChatGPT 使用自注意力机制对 prompt 进行反复编码,其时间和内存...【详细内容】
2023-05-08  Search: Token  点击:(242)  评论:(0)  加入收藏
无感知刷新Token
引言在前后端分离的应用中,使用Token进行认证是一种较为常见的方式。但是,由于Token的有效期限制,需要不断刷新Token,否则会导致用户认证失败。为了解决这个问题,可以实现无感知...【详细内容】
2023-04-04  Search: Token  点击:(235)  评论:(0)  加入收藏
▌简易百科推荐
Netflix 是如何管理 2.38 亿会员的
作者 | Surabhi Diwan译者 | 明知山策划 | TinaNetflix 高级软件工程师 Surabhi Diwan 在 2023 年旧金山 QCon 大会上发表了题为管理 Netflix 的 2.38 亿会员 的演讲。她在...【详细内容】
2024-04-08    InfoQ  Tags:Netflix   点击:(0)  评论:(0)  加入收藏
即将过时的 5 种软件开发技能!
作者 | Eran Yahav编译 | 言征出品 | 51CTO技术栈(微信号:blog51cto) 时至今日,AI编码工具已经进化到足够强大了吗?这未必好回答,但从2023 年 Stack Overflow 上的调查数据来看,44%...【详细内容】
2024-04-03    51CTO  Tags:软件开发   点击:(6)  评论:(0)  加入收藏
跳转链接代码怎么写?
在网页开发中,跳转链接是一项常见的功能。然而,对于非技术人员来说,编写跳转链接代码可能会显得有些困难。不用担心!我们可以借助外链平台来简化操作,即使没有编程经验,也能轻松实...【详细内容】
2024-03-27  蓝色天纪    Tags:跳转链接   点击:(13)  评论:(0)  加入收藏
中台亡了,问题到底出在哪里?
曾几何时,中台一度被当做“变革灵药”,嫁接在“前台作战单元”和“后台资源部门”之间,实现企业各业务线的“打通”和全域业务能力集成,提高开发和服务效率。但在中台如火如荼之...【详细内容】
2024-03-27  dbaplus社群    Tags:中台   点击:(9)  评论:(0)  加入收藏
员工写了个比删库更可怕的Bug!
想必大家都听说过删库跑路吧,我之前一直把它当一个段子来看。可万万没想到,就在昨天,我们公司的某位员工,竟然写了一个比删库更可怕的 Bug!给大家分享一下(不是公开处刑),希望朋友们...【详细内容】
2024-03-26  dbaplus社群    Tags:Bug   点击:(5)  评论:(0)  加入收藏
我们一起聊聊什么是正向代理和反向代理
从字面意思上看,代理就是代替处理的意思,一个对象有能力代替另一个对象处理某一件事。代理,这个词在我们的日常生活中也不陌生,比如在购物、旅游等场景中,我们经常会委托别人代替...【详细内容】
2024-03-26  萤火架构  微信公众号  Tags:正向代理   点击:(11)  评论:(0)  加入收藏
看一遍就理解:IO模型详解
前言大家好,我是程序员田螺。今天我们一起来学习IO模型。在本文开始前呢,先问问大家几个问题哈~什么是IO呢?什么是阻塞非阻塞IO?什么是同步异步IO?什么是IO多路复用?select/epoll...【详细内容】
2024-03-26  捡田螺的小男孩  微信公众号  Tags:IO模型   点击:(9)  评论:(0)  加入收藏
为什么都说 HashMap 是线程不安全的?
做Java开发的人,应该都用过 HashMap 这种集合。今天就和大家来聊聊,为什么 HashMap 是线程不安全的。1.HashMap 数据结构简单来说,HashMap 基于哈希表实现。它使用键的哈希码来...【详细内容】
2024-03-22  Java技术指北  微信公众号  Tags:HashMap   点击:(11)  评论:(0)  加入收藏
如何从头开始编写LoRA代码,这有一份教程
选自 lightning.ai作者:Sebastian Raschka机器之心编译编辑:陈萍作者表示:在各种有效的 LLM 微调方法中,LoRA 仍然是他的首选。LoRA(Low-Rank Adaptation)作为一种用于微调 LLM(大...【详细内容】
2024-03-21  机器之心Pro    Tags:LoRA   点击:(12)  评论:(0)  加入收藏
这样搭建日志中心,传统的ELK就扔了吧!
最近客户有个新需求,就是想查看网站的访问情况。由于网站没有做google的统计和百度的统计,所以访问情况,只能通过日志查看,通过脚本的形式给客户导出也不太实际,给客户写个简单的...【详细内容】
2024-03-20  dbaplus社群    Tags:日志   点击:(4)  评论:(0)  加入收藏
站内最新
站内热门
站内头条