前端刷新token,判断token是否过期(jwt鉴权)

news2025/1/24 10:53:23

4.1 什么是 JWT
JWT 是 Auth0 提出的通过 对 JSON 进行加密签名来实现授权验证的方案;
就是登录成功后将相关用户信息组成 JSON 对象,然后对这个对象进行某种方式的加密,返回给客户端;
客户端在下次请求时带上这个 Token;
服务端再收到请求时校验 token 合法性,其实也就是在校验请求的合法性。
4.2 JWT 的组成
JWT 由三部分组成: Header 头部、 Payload 负载 和 Signature 签名
它是一个很长的字符串,中间用点(.)分隔成三个部分。列如 :

`eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c`

Header 头部:
在 Header 中通常包含了两部分:

typ:代表 Token 的类型,这里使用的是 JWT 类型;
alg:使用的 Hash 算法,例如 HMAC SHA256 或 RSA.

 {
   "alg": "HS256",
   "typ": "JWT"
 }

Payload 负载:
它包含一些声明 Claim (实体的描述,通常是一个 User 信息,还包括一些其他的元数据) ,用来存放实际需要传递的数据,JWT 规定了7个官方字段:

iss (issuer):签发人
exp (expiration time):过期时间
sub (subject):主题
aud (audience):受众
nbf (Not Before):生效时间
iat (Issued At):签发时间
jti (JWT ID):编号

除了官方字段,你还可以在这个部分定义私有字段,下面就是一个例子。

 {
   "sub": "1234567890",
   "name": "John Doe",
   "admin": true
 }

Signature 签名
Signature 部分是对前两部分的签名,防止数据篡改。
首先,需要指定一个密钥(secret)。这个密钥只有服务器才知道,不能泄露给用户。然后,使用 Header 里面指定的签名算法(默认是 HMAC SHA256),按照下面的公式产生签名。

 HMACSHA256(
   base64UrlEncode(header) + "." +
   base64UrlEncode(payload),
   secret)

4.3 JWT 的使用方式
客户端收到服务器返回的 JWT,可以储存在 Cookie 里面,也可以储存在 localStorage。
此后,客户端每次与服务器通信,都要带上这个 JWT。你可以把它放在 Cookie 里面自动发送,但是这样不能跨域,所以更好的做法是放在 HTTP 请求的头信息Authorization字段里面。

 Authorization: Bearer <token>

4.4 JWT 的认证流程图
其实 JWT 的认证流程与 Token 的认证流程差不多,只是不需要再单独去查询数据库查找用户用户;简要概括如下:
在这里插入图片描述

4.5 JWT 的优点

不需要在服务端保存会话信息(RESTful API 的原则之一就是无状态),所以易于应用的扩展,即信息不保存在服务端,不会存在 Session 扩展不方便的情况;
JWT 中的 Payload 负载可以存储常用信息,用于信息交换,有效地使用 JWT,可以降低服务端查询数据库的次数

4.6 JWT 的缺点

加密问题: JWT 默认是不加密,但也是可以加密的。生成原始 Token 以后,可以用密钥再加密一次。
到期问题: 由于服务器不保存 Session 状态,因此无法在使用过程中废止某个 Token,或者更改 Token 的权限。也就是说,一旦 JWT 签发了,在到期之前就会始终有效,除非服务器部署额外的逻辑。

5.判断token是否过期

1、刷新令牌(Refresh Token)

    在用户登录时,除了发放一个访问令牌(Access Token)以外,再发放一个刷新令牌(Refrsh Token)。

    访问令牌的有效期比较短,刷新令牌的有效期比较长。

    当访问令牌过期时,使用刷新令牌向服务器请求新的访问令牌。如果刷新令牌也过期,则跳转回登录界面。

    这种方式的优点是可以避免用户频繁登录,但需要妥善保管刷新令牌,因为它的安全性比访问令牌更高。

一般会根据时间戳判断时间是否超过有效期时间(可借鉴下面的例子进行操作)

login.js中,登录后设置即将过期时间:

import {setTokenOverdueTime} from '../src/api/refreshToken'
localStorage.setItem("tokenOverdueTime", setTokenOverdueTime());
1
2
新建一个refreshToken.js文件,文件内容如下:

import Vue from 'vue'

//设置token快过期时间,当前时间+20分钟
export function setTokenOverdueTime() {
    let t = new Date().getTime() + 1200000;
    let d = new Date(t);
    let theMonth = d.getMonth() + 1;
    let theDate = d.getDate();
    let theHours = d.getHours();
    let theMinutes = d.getMinutes();
    if (theMonth < 10) {
        theMonth = '0' + theMonth
    }
    if (theDate < 10) {
        theDate = '0' + theDate
    }
    if (theHours < 10) {
        theHours = '0' + theHours
    }
    if (theMinutes < 10) {
        theMinutes = '0' + theMinutes
    }
    let date = d.getFullYear() + '-' + theMonth + '-' + theDate
    let time = theHours + ':' + theMinutes
    let Spare = date + ' ' + time
    return Spare;
}

// 判断token是否即将过期
function isTokenExpired() {
    let curTime = new Date();
    //获取即将过期时间
    let tokenOverdueTime = localStorage.getItem("tokenOverdueTime");
    // 判断当前时间是否大于即将过期时间
    if (curTime > new Date(tokenOverdueTime)) {
        return true
    }
    return false;
}
// 将所有的请求都push到数组中,其实数组是[function(token){}, function(token){},...]
function cacheRequestArrHandle(cb) {
    cacheRequestArr.push(cb);
}
// 数组中的请求得到新的token之后自执行,用新的token去重新发起请求
function afreshRequest(token) {
    cacheRequestArr.map(cb => cb(token));
    cacheRequestArr = [];
}
//定义一个空数组,用来缓存请求
let cacheRequestArr = [];
// 是否正在刷新的标志
window.isRefreshing = false;
export function isRefreshToken(instance, config, store) {
	// 判断token是否即将过期,且不是请求刷新token的接口
    if(isTokenExpired() && config.url !== '/refreshToken'){
    	// 所有的请求来了,先判断是否正在刷新token,
        // 如果不是,将刷新token标志置为true并请求刷新token.
        // 如果是,则先将请求缓存到数组中
        // 等到刷新完token后再次重新请求之前缓存的请求接口即可
        if (!window.isRefreshing) {
            window.isRefreshing = true;
            instance.get('/refreshToken').then(res => {
                if(res.data.status === 0){
                	// 更新 store和缓存里的值
                    localStorage.setItem("userToken", JSON.stringify(res.data.data));
                    store.dispatch("setUserToken", res.data.data);
                    // 更新即将过期时间
                    localStorage.setItem("tokenOverdueTime", setTokenOverdueTime());
                    // 将刷新的token替代老的token
                    config.headers.token = res.data.data;
                    // 刷新token完成后重新请求之前的请求
                    afreshRequest(res.data.data);
                }
            }).finally(() => {
                window.isRefreshing = false;
            })
            // 下面这段代码一定要写,不然第一个请求的接口带过去的token还是原来的,要将第一个请求也缓存起来
            let retry = new Promise((resolve) => {
                cacheRequestArrHandle((token) => {
                    config.headers.token = token; // token为刷新完成后传入的token
                    // 将请求挂起
                    resolve(config)
                })
            })
            return retry;
        }
        else{
            let retry = new Promise((resolve) => {
                cacheRequestArrHandle((token) => {
                    config.headers.token = token; // token为刷新完成后传入的token
                    // 将请求挂起
                    resolve(config)
                })
            })
            return retry;
        }
    }
    else{
        return config
    }
}

设置拦截器:

import store from '../../store';
import {isRefreshToken} from '../src/api/refreshToken'
/**
 * 请求拦截
 * interceptors
 * @param instance
 * */
export const interceptors = (instance) => {
    //请求拦截
    instance.interceptors.request.use(config => {
        //  请求头携带token 和env
        let token = localStorage.getItem("userToken") ? JSON.parse(localStorage.getItem("userToken")) : null;
        if(token){
            config.headers.token = token;
        }
        let flag = isRefreshToken(instance, config, store);
        return flag ? flag : config;
    }, (error) => {
        return Promise.reject(error);
    })
    //响应拦截
    instance.interceptors.response.use(res => {
        //返回数据
        if(res.data.dev) return res;
        if (res.data.code !== 0) {
            return Promise.reject(res);
        }else {
            return res;
        }
    }, (error) => {
        return Promise.reject(error);
    })

2、滑动窗口

    用户每次使用使用访问令牌时,服务器都会更新访问令牌的过期时间。

    这种方式的优点是用户只要频繁访问,就不需要登录,但可能会增加服务器负担。

3、重新登录

    当访问令牌过期时,跳转回登录界面,让用户重新登录。这是最简单的一种方式,但可能会影响用户体验。

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

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

相关文章

Python网络编程改良版服务端

在《Python中套接字实现服务端和客户端3-1》中提到服务端可以接收来自客户端的连接&#xff0c;并且创造新的套接字与客户端进行数据通信。此时的服务端只能与一个客户端进行数据通信&#xff0c;如果有多个客户端连接服务端&#xff0c;该怎么对服务端进行改良呢&#xff1f; …

全流程TOUGH系列软件应用丨入门丨基础丨进阶丨实操

TOUGH系列软件是由美国劳伦斯伯克利实验室开发的&#xff0c;旨在解决非饱和带中地下水、热运移的通用模拟软件。和传统地下水模拟软件Feflow和Modflow不同&#xff0c;TOUGH系列软件采用模块化设计和有限积分差网格剖分方法&#xff0c;通过配合不同状态方程&#xff08;EOS模…

100.一个linux内核选项对ssh的影响

&#xff08;从这开始给文章编号&#xff0c;编号从100开始&#xff09; 平台&#xff1a;rk3399&#xff08;f4932-r2h&#xff09; 内核&#xff1a;linux5.10 文件系统&#xff1a;firefly ssh&#xff1a;有线网卡 串口终端打印正常&#xff0c; 但是ssh登录却出现如下…

Xshell7试用期过了,打开就显示评估期已过,想继续或者不能删除怎么办?详细说明解决步骤

文章目录 1、问题说明2、解决办法2.1 重新安装2.2 卸载 1、问题说明 多长时间没用 Xshell 远程连接服务器&#xff0c;发现之前没有使用魔法工具处理&#xff08;正版&#xff09;&#xff0c;现在过期了。 2、解决办法 想继续使用Xshell的话&#xff0c;有两种方式&#xff…

全光谱台灯对孩子眼睛好吗?2023五款全光谱护眼台灯推荐

全光谱台灯是一种能够模拟自然光谱的照明设备&#xff0c;其光线成分丰富&#xff0c;更接近自然阳光的光谱。相比传统的白炽灯或荧光灯&#xff0c;全光谱台灯在照明效果上更加均匀柔和&#xff0c;并且可以提供更好的颜色还原效果。对于孩子的眼睛来说&#xff0c;全光谱台灯…

ios UI 基础开发二

第一节&#xff1a;UIPickerView、UIPickerViewDataSource、UIPickerViewDelegate 设置约束&#xff0c;如果要设置两个兄弟的约束&#xff0c;可以按住option键&#xff0c;用鼠标右键把a拖到b上面&#xff0c;表示a按照b来对齐 生成随机数 如果后面列的数据&#xff0c;依赖前…

JL-03多场合通用型小型气象站

JL-03小型气象站&#xff0c;用于对风速、风向、雨量、空气温度、空气湿度、太阳辐射、光照强度、土壤温度、土壤湿度、蒸发量、大气压力等气象要素进行监测。既可以通过无线通讯将数据传送至云平台&#xff0c;又可以通过配套的数据采集通讯线与计算机进行连接&#xff0c;将数…

ARP协议

ARP协议 文章目录 ARP协议ARP协议的作用ARP协议的定位ARP数据报的格式ARP协议的工作流程ARP缓存表RARP协议 地址解析协议&#xff0c;即ARP&#xff08;Address Resolution Protocol&#xff09;&#xff0c;是根据IP地址获取物理地址的一个TCP/IP协议。 ARP协议的作用 ARP协议…

手机爬虫用Scrapy详细教程:构建高效的网络爬虫

如果你正在进行手机爬虫的工作&#xff0c;并且希望通过一个高效而灵活的框架来进行数据抓取&#xff0c;那么Scrapy将会是你的理想选择。Scrapy是一个强大的Python框架&#xff0c;专门用于构建网络爬虫。今天&#xff0c;我将与大家分享一份关于使用Scrapy进行手机爬虫的详细…

2023最令人心动的短视频配音软件

配音在影视、广告和动画等领域中起着非常重要的作用&#xff0c;可以为作品增添情感和戏剧性。然而&#xff0c;许多人不知道如何制作配音&#xff0c;如果你也是这样&#xff0c;一定要花一分钟看完这篇文章。 其实现在有一些AI智能配音软件就很好用&#xff0c;可以帮助我们…

Windows安装SNMP服务

windows10安装SNMP服务 打开计算机的设置–应用–应用和功能–可选功能–点击加号添加功能,添加以下两个功能: windows server安装SNMP服务 搜索打开服务器管理器,点击功能–添加功能,勾选SNMP服务,点击下一步,等待安装完成 按win+R快捷键,运行service.msc,在服务中将…

电脑D盘文件凭空消失了?切记3招,轻松恢复文件!

“由于我c盘内存不够了&#xff0c;我就将部分重要的文件保存到了d盘&#xff0c;今天打开d盘后才发现我这些文件凭空消失了。这究竟是什么呀&#xff1f;还有机会找回这些消失的d盘文件吗&#xff1f;” D盘作为电脑中一个重要的磁盘&#xff0c;很多电脑用户也会选择将文件保…

摩尔信使MThings的协议转换(数据网关)功能

摩尔信使MThings可以作为现场总线&#xff08;RS485&#xff09;和以太网的数据中枢&#xff0c;并拥有强大的Modbus协议转换功能。 数据网关功能提供协议转换和数据汇聚功能&#xff0c;可实现多维度映射&#xff0c;包括&#xff1a;不同的通道(总线)类型、协议类型&#xff…

QSpace Pro 4.0.4.001(多面板文件管理器)

QSpace是一个干净高效的多面板文件管理器&#xff0c;也可以连接到FTP&#xff0c;SFTP&#xff0c;WebDAV&#xff0c;Dropbox&#xff0c;OneDrive&#xff0c;GoogleDrive&#xff0c;Amazon S3&#xff08;和S3兼容&#xff09;&#xff0c;Aliyun OSS。它具有与Finder相同…

调优C / C ++编译器以在多核应用程序中获得最佳并行性能:第一部分

领取嵌入式物联网学习路线对于希望通过多核设计中的多线程或分区利用并行性的而言&#xff0c;重要的第一步是提高应用程序的标量性能。 更好&#xff0c;更轻松的方法之一是应用积极的编译器优化。面向您的处理器并具有高级优化功能&#xff08;例如自动矢量化&#xff0c;过…

多维时序 | MATLAB实现SSA-CNN-BiGRU-Attention多变量时间序列预测(SE注意力机制)

多维时序 | MATLAB实现SSA-CNN-BiGRU-Attention多变量时间序列预测&#xff08;SE注意力机制&#xff09; 目录 多维时序 | MATLAB实现SSA-CNN-BiGRU-Attention多变量时间序列预测&#xff08;SE注意力机制&#xff09;预测效果基本描述模型描述程序设计参考资料 预测效果 基本…

身份证二要素核验API:提高身份验证的便捷性与安全性

引言 随着数字化时代的不断发展&#xff0c;身份验证变得愈发重要。在互联网上&#xff0c;身份验证是保护用户隐私和数据安全的关键环节。为了满足这一需求&#xff0c;身份证二要素核验API应运而生&#xff0c;成为提高身份验证的便捷性与安全性的得力工具。 身份验证的重要…

成都爱尔周进院长解读不同近视手术的不同度数要求

常有人这么问&#xff1a;我xx度了还能做近视手术吗?我才xx度也能做近视手术吗? 度数&#xff0c;确实是自己掌握地最清楚“最直观”的一个数据。 要说屈光手术的指标&#xff0c;有角膜曲率、角膜厚度、角膜地形等非常之多。 但这些数据不做详细检查自己根本不知道&#xff…

实战讲解 SpringBoot 定时任务:@Scheduled

最近的开发中又遇到了关于定时调度的开发任务&#xff0c;在定时调度其实有很多的第三方平台可以接入&#xff0c;但是其实在SpringBoot有自带的定时任务注解Scheduled。Scheduled可以通过注解配置快速实现方法的定时调度&#xff0c;直接在方法加上Scheduled注解即可。 1Sche…

什么牌子的led台灯质量好?五款Led护眼台灯推荐

led台灯有环保无污染、耗能低、长寿命等优点&#xff0c;适合用在阅读、书写、批阅等办公或学习的场所。而挑选LED台灯时&#xff0c;分散光挡板做的比较好的优先选择&#xff0c;能分散大量蓝光&#xff0c;对眼睛危害较小。下面&#xff0c;小编为大家推荐五款质量好的led护眼…