Asp.Net Core中JWT刷新Token解决方案【转】

摘要:
1、 前言1.JWT令牌将过期多长时间?(1). 有些人将到期时间设置得很长,例如一个月,甚至更长。到期后,他们返回登录页面,再次登录,并再次获取令牌。在登录期间,他们还会再次获得令牌,然后将到期时间重置为一个月。通过这种方式,一旦令牌被拦截,它可能会被长期使用。如果要禁止它,则只能修改令牌颁发的密钥,这将导致所有令牌无效。这显然是不可取的。(2) 。有些人的设置很短

一. 前言

1.关于JWT的Token过期问题,到底设置多久过期?

(1).有的人设置过期时间很长,比如一个月,甚至更长,等到过期了退回登录页面,重新登录重新获取token,期间登录的时候也是重新获取token,然后过期时间又重置为了1个月。这样一旦token被人截取,就可能被人长期使用,如果你想禁止,只能修改token颁发的密钥,这样就会导致所有token都失效,显然不太可取。

(2).有的人设置比较短,比如10分钟,在使用过程中,一旦过期也是退回登录页面,这样就可能使用过程中经常退回登录页面,体验很不好。

2. 这里介绍一种比较主流的解决方案---双Token机制

(1).访问令牌:accessToken,访问接口是需要携带的,也就是我们之前一直使用的那个,过期时间一般设置比较短,根据实际项目分析,比如:10分钟

(2).刷新令牌:refreshToken,当accessToken过期后,用于获取新的accessToken的时候使用,过期时间一般设置的比较长,比如:7天

3.获取新的accessToken的时候, 为什么还需要传入旧accessToken,只传入refreshToken不行么?

 仔细看下面的解决思路,只传入refreshToken也可以,但是传入双Token安全性更高一些。

二. 解决方案

1. 登录请求过来,将userId和userAccount存到payLoad中,设置不同的过期时间,分别生成accessToken和refreshToken,二者的区别密钥不一样,过期时间不一样,然后把 生成refreshToken的相关信息存到对应的表中【id,userId,token,expire】,一个用户对应一条记录(也可以存到Redis中,这里为了测试,存在一个全局变量中), 每次登录的时候,添加或者更新记录,最后将双Token返回给前端,前端存到LocalStorage中。

 Asp.Net Core中JWT刷新Token解决方案【转】第1张Asp.Net Core中JWT刷新Token解决方案【转】第2张

2. 前端访问GetMsg获取信息接口,表头需要携带accessToken,服务器端通过JwtCheck2过滤器进行校验,验证通过则正常访问,如果不通过返回401和不通过的原因,前端在Error中进行获取,这里区分造成401的原因。

复制代码
 1 //获取信息接口
 2         function GetMsg() {
 3             var accessToken = window.localStorage.getItem("accessToken");      
 4             $.ajax({
 5                 url: "/Home/GetMsg",
 6                 type: "Post",
 7                 data: {},
 8                 datatype: "json",
 9                 beforeSend: function (xhr) {
10                     xhr.setRequestHeader("Authorization", "Bearer " + accessToken);
11                 },
12                 success: function (data) {
13                     if (data.status == "ok") {
14                         alert(data.msg);
15                     } else {
16                         alert(data.msg);
17                     }
18                 },
19                 //当安全校验未通过的时候进入这里
20                 error: function (xhr) {
21                     if (xhr.status == 401) {
22                         var errorMsg = xhr.responseText;
23                         console.log(errorMsg);
24                         //alert(errorMsg);
25                         if (errorMsg == "expired") {
26                             //表示过期,需要自动刷新
27                             GetTokenAgain(GetMsg);
28                         } else {
29                             //表示是非法请求,给出提示,可以直接退回登录页
30                             alert("非法请求");
31                         }
32                     }
33                 }
34             });
35         }
复制代码

3. 如果是表头为空、校验错误等等,则直接提示请求非法,返回登录页。

Asp.Net Core中JWT刷新Token解决方案【转】第5张

4. 如果捕获的是expired即过期,则调用GetTokenAgain(func)方法,即重新获取accessToken和refreshToken,这里func代表传递进来一个方法名,以便调用成功后重新调用原方法,实现无缝刷新; 向服务器端传递 双Token, 服务器端的验证逻辑如下:

(1). 先通过纯代码校验refreshToken的物理合法性,如果非法,前端直接报错,返回到登录页面。

(2). 从accessToken中解析出来userId等其它数据(即使accessToken已经过期,依旧可以解析出来)

(3). 拿着userId、refreshToken、当前时间去RefreshToken表中查数据,如果查不到,直接返回前端保存,返回到登录页面。

(4). 如果能查到,重新生成 accessToken和refreshToken,并写入RefreshToken表

(5). 向前端返回双token,前端进行覆盖存储,然后自动调用原方法,携带新的accessToken,进行访问,从而实现无缝刷新token的问题。

复制代码
 1  //重新获取访问令牌和刷新令牌
 2         function GetTokenAgain(func) {
 3             var model = {
 4                 accessToken: window.localStorage.getItem("accessToken"),
 5                 refreshToken: window.localStorage.getItem("refreshToken")
 6             };
 7             $.ajax({
 8                 url: '/Home/UpdateAccessToken',
 9                 type: "POST",
10                 dataType: "json",
11                 data: model,
12                 success: function (data) {
13                     if (data.status == "error") {
14                         debugger;
15                         // 表示重新获取令牌失败,可以退回登录页
16                         alert("重新获取令牌失败");
17 
18                     } else {
19                         window.localStorage.setItem("accessToken", data.data.accessToken);
20                         window.localStorage.setItem("refreshToken", data.data.refreshToken);
21                         func();
22                     }
23                 }
24             });
复制代码

PS:以上方案,适用于单个页面发送单个ajax请求,如果是多个请求,有顺序的发送,比如第一个发送完,然后再发送第二个,这种场景是没问题的。

但是,特殊情况如果一个页面多个ajax并行的过来了,如果其中有一个accessToken过期了,那么它会走更新token的机制,这时候refreshToken和accessToken都更新了(数据库中refreshToken也更新了),会导致刚才同时进来的其它ajax的refreshToken验证不过,从而无法刷新双token。

针对这种特殊情况,作为取舍,更新accessToken的方法中,不更新refreshToken, 那么refreshToken过期,本来也是要进入 登录页的,所以针对这类情况,这种取舍也无可厚非。

 转:https://www.cnblogs.com/yaopengfei/p/12449213.html

免责声明:文章转载自《Asp.Net Core中JWT刷新Token解决方案【转】》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇玩转树莓派《三》——ScratchKVM配置及维护下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Django-REST-Framework JWT 实现SSO认证(下)

在上一篇博客中,我已经对JSON Web 认证做了简单的解释,这篇博客是续篇,若不了解,请看上一篇博客:https://www.cnblogs.com/yushenglin/p/10863184.html 一.安装djangorestframwork-jwt 二.用法 在你的settings.py,添加JSONWebTokenAuthentication...

SpringBootSecurity学习(19)前后端分离版之OAuth2.0 token的存储和管理

内存中存储token 我们来继续授权服务代码的下一个优化。现在授权服务中,token的存储是存储在内存中的,我们使用的是 InMemoryTokenStore : 图中的tokenStore方法支持很多种令牌的存储方式,来看一下: InMemoryTokenStore:这个版本的实现是被默认采用的,它可以完美的工作在单服务器上(即访问并发量压力不大的情...

token解决前后端分离认证和跨域问题和JWT的使用

二、使用token解决前端后端分离用户认证问题 2.1 用户提交帐号和密码到服务器的认证接口 login.html doSubmit:function(){ console.log("~~~~~~~~~~~~~doSubmit"); axios.get("http://localhost:8080/user/login",{...

FastAPI 学习之路(二十六)全局依赖项

  有时,我们要为整个应用添加依赖项。通过与定义FastAPI 学习之路(二十五)路径操作装饰器依赖项 类似的方式,可以把依赖项添加至整个 FastAPI 应用。         那么我们看下,如何去实现,比如我们全局都需要校验token。我们去看下,我们应该如何实现代码。 from fastapi import FastAPI,Header, HTTP...

微信公众平台开发——helloworld

威信公众平台有两种模式:编辑模式 和 开发模式。 普通的功能可以通过编辑模式来搞定。开发模式具有更多的功能。让我们来使用开发模式开发helloword吧 步骤如下: 1.先注册一个公众号(https://mp.weixin.qq.com) 2.注册sae(http://sae.sina.com.cn/),作为你的服务器。 3.登录微信公众平台(https:...

微信开发笔记:获取用户openid,以及用户头像昵称等信息

微信开发的时候有一个很便利的途径来进行一个用户的一步注册登录,就是使用用户的微信信息来直接进行登陆,可以省去很多不必要的麻烦。那具体这些信息是如何来获取的呢? 首先呢,我们需要对微信进行一个授权,让微信页面有权限来读取我们的用户信息: $redirect_uri = urlencode($url); //设置授权页面,此处填写回调的授权页面地址 $scop...