ASP.NET Core Web Api之JWT刷新Token(三)

本节我们进入JWT最后一节内容,JWT本质上就是从身份认证服务器获取访问令牌,继而对于用户后续可访问受保护资源,但是关键问题是:访问令牌的生命周期到底设置成多久呢?
见过一些使用JWT的童鞋会将JWT过期时间设置成很长,有的几个小时,有的一天,有的甚至一个月,这么做当然存在问题,如果被恶意获得访问令牌,那么可在整个生命周期中使用访问令牌,也就是说存在冒充用户身份,此时身份认证服务器当然也就是始终信任该冒牌访问令牌
若要使得冒牌访问令牌无效,唯一的方案则是修改密钥,但是如果我们这么做了,则将使得已授予的访问令牌都将无效,所以更改密钥不是最佳方案,我们应该从源头尽量控制这个问题,而不是等到问题呈现再来想解决之道,刷新令牌闪亮登场。


什么是刷新令牌呢?刷新访问令牌是用来从身份认证服务器交换获得新的访问令牌,有了刷新令牌可以在访问令牌过期后通过刷新令牌重新获取新的访问令牌而无需客户端通过凭据重新登录,如此一来,既保证了用户访问令牌过期后的良好体验,也保证了更高的系统安全性
同时,若通过刷新令牌获取新的访问令牌验证其无效可将受访者纳入黑名单限制其访问,那么访问令牌和刷新令牌的生命周期设置成多久合适呢?这取决于系统要求的安全性,一般来讲访问令牌的生命周期不会太长,比如5分钟,又比如获取微信的AccessToken的过期时间为2个小时。
接下来我将用两张表来演示实现刷新令牌的整个过程,可能有更好的方案,欢迎在评论中提出,学习,学习。我们新建一个http://localhost:5000的WebApi用于身份认证,再新建一个http://localhost:5001的客户端,首先点击【模拟登录获取Toen】获取访问令牌和刷新令牌,然后点击【调用客户端获取当前时间】,如下:


640?wx_fmt=png接下来我们新建一张用户表(User)和用户刷新令牌表(UserRefreshToken),结构如下:640?wx_fmt=png640?wx_fmt=png如上可以看到对于刷新令牌的操作我们将其放在用户实体中,也就是使用EF Core中的Back Fields而不对外暴露。接下来我们将生成的访问令牌、刷新令牌、验证访问令牌、获取用户身份封装成对应方法如下:640?wx_fmt=png640?wx_fmt=png当用户点击登录,访问身份认证服务器,登录成功后我们创建访问令牌和刷新令牌并返回,如下:640?wx_fmt=png此时我们回到如上给出的图,我们点击【模拟登录获取Token】,此时发出Ajax请求,然后将返回的访问令牌和刷新令牌存储到本地localStorage中,如下:640?wx_fmt=png640?wx_fmt=png640?wx_fmt=png此时我们再来点击【调用客户端获取当前时间】,同时将登录返回的访问令牌设置到请求头中,代码如下:640?wx_fmt=png客户端请求接口很简单,为了让大家一步步看明白,我也给出来,如下:640?wx_fmt=png好了到了这里我们已经实现模拟登录获取访问令牌,并能够调用客户端接口获取到当前时间,同时我们也只是返回了刷新令牌并存储到了本地localStorage中,并未用到。当访问令牌过期后我们需要通过访问令牌和刷新令牌去获取新的访问令牌,对吧。
那么问题来了。我们怎么知道访问令牌已经过期了呢?这是其一,其二是为何要发送旧的访问令牌去获取新的访问令牌呢?直接通过刷新令牌去换取不行吗?有问题是好的,就怕没有任何思考,我们一一来解答。我们在客户端添加JWT中间件时,里面有一个事件可以捕捉到访问令牌已过期(关于客户端配置JWT中间件第一节已讲过,这里不再啰嗦),如下:640?wx_fmt=png通过如上事件并捕捉访问令牌过期异常,这里我们在响应头添加了一个自定义键act,值为expired,因为一个401只能反映未授权,并不能代表访问令牌已过期。当我们在第一张图中点击【调用客户端获取当前时间】发出Ajax请求时,如果访问令牌过期,此时在Ajax请求中的error方法中捕捉到,我们在如上已给出发出Ajax请求的error方法中继续进行如下补充:640?wx_fmt=png到了这里我们已经解决如何捕捉到访问令牌已过期的问题,接下来我们需要做的则是获取刷新令牌,直接通过刷新令牌换取新的访问令牌也并非不可,只不过还是为了安全性考虑,我们加上旧的访问令牌。接下来我们发出Ajax请求获取刷新令牌,如下:640?wx_fmt=png发出Ajax请求获取刷新令牌的方法我们传入了一个函数,这个函数则是上一次调用接口访问令牌过期的请求,点击【调用客户端获取当前时间】按钮的Ajax请求error方法中,最终演变成如下这般:640?wx_fmt=png接下来则是通过传入旧的访问令牌和刷新令牌调用接口换取新的访问令牌,如下:640?wx_fmt=png640?wx_fmt=png如上通过传入旧的访问令牌验证并获取用户身份,然后验证刷新令牌是否已经过期,如果未过期则创建新的访问令牌,同时更新刷新令牌。最终客户端访问令牌过期的那一刻,通过刷新令牌获取新的访问令牌继续调用上一请求,如下:640?wx_fmt=png


到这里关于JWT实现刷新Token就已结束,自我感觉此种实现刷新令牌将其存储到数据库的方案还算可取,将刷新令牌存储到Redis也可行,看个人选择吧。上述若刷新令牌验证无效,可将访问者添加至黑名单,不过是添加一个属性罢了。别着急,本节内容结束前,还留有彩蛋。


无论是看视频还是看技术博客也好,一定要动手验证,看到这里觉得上述我所演示是不是毫无问题,如果阅读本文的你直接拷贝上述代码你会发现有问题,且听我娓娓道来,让我们来复习下Back Fields。Back Fields命名是有约定dei,上述我是根据约定而命名,所以千万别一意孤行,别乱来,比如如下命名将抛出如下异常:640?wx_fmt=png640?wx_fmt=png上述我们配置刷新令牌的Back Fields,代码如下:640?wx_fmt=png640?wx_fmt=png要是我们配置成如下形式,结果又会怎样呢?640?wx_fmt=png640?wx_fmt=png此时为了解决这个问题,我们必须将其显式配置成Back Fields,如下:640?wx_fmt=png在我个人著作中也讲解到为了性能问题,可将字段进行ToList(),若进行了ToList(),必须显式配置成Back Fields,否则获取不到刷新令牌导航属性,如下:640?wx_fmt=png或者进行如下配置,我想应该也可取,不会存在性能问题,如下:640?wx_fmt=png这是关于Back Fields问题之一,问题之二则是上述我们请求获取刷新令牌中,我们先在刷新令牌的Back Fields中移除掉旧的刷新令牌,而后再创建新的刷新令牌,但是会抛出如下异常:640?wx_fmt=png640?wx_fmt=png我们看到在添加刷新令牌时,用户Id是有值的,对不对,这是为何呢?究其根本问题出在我们移除刷新令牌方法中,如下:640?wx_fmt=png我们将查询出来的导航属性并将其映射到_userRefreshTokens字段中,此时是被上下文所追踪,上述我们查询出存在的刷新令牌并在跟踪的刷新令牌中进行移除,没毛病,没找到原因,于是乎,我将上述方法修改成如下看看是否必须需要主键才能删除旧的刷新令牌:640?wx_fmt=png倒没抛出异常,创建了一个新的刷新令牌,但是旧的刷新令牌却没删除,如下:640?wx_fmt=png至此未找到问题出在哪里,当前版本为2.2,难道不能通过Back Fields移除对象?这个问题待解决。


本节我们重点讲解了如何实现JWT刷新令牌,并也略带讨论了EF Core中Back Fields以及尚未解决的问题,至此关于JWT已结束,下节开始正式进入Docker小白系列,感谢阅读。

640?wx_fmt=jpeg


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

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

相关文章

简单dfs序 + 树链剖分

树链剖分 DFS序 先来讲一讲DFS序是什么东西,直接上图,方便理解。 估计巨巨们应该知道了DFS序的两个重要的东西,in,outin,outin,out数组。 ininin数组就是这个点进入DFS的时间。outoutout数组就是这个点退出DFS递归栈的时间。这个时间要注意…

WeihanLi.Npoi 导出支持自定义列内容啦

WeihanLi.Npoi 导出支持自定义列内容啦Intro之前也有网友给提出过希望列合并或者自定义列内容的 issue 或请求&#xff0c;起初因为自己做 WeihanLi.Npoi 这个扩展的最初目的是导入导出的简单化&#xff0c;使用这个扩展导出的 Excel/csv 可以直接导入成 List<TEntity>&a…

让 .Net 更方便的导入导出 Excel

让 .Net 更方便的导入导出ExcelIntro因为前一段时间需要处理一些 excel 数据&#xff0c;主要是导入/导出操作&#xff0c;将 Excel 数据转化为对象再用程序进行处理和分析&#xff0c;没有找到比较满意的库&#xff0c;于是就自己造了一个轮子&#xff0c;屏蔽掉了 xlsx 与 xl…

最大流,最小费用最大流:解析 + 各种板子

网络流初步 Edmond-Karp算法 网络流的基本概念 源点&#xff0c;这个点只有流量的流出&#xff0c;没有流入。汇点&#xff0c;这个点只有流量的流入&#xff0c;没有流出。容量&#xff0c;每条有向边的最大可承受的流的理论大小。流量&#xff0c;每条有向边的最大可承受的…

Zend创始人离职原来早已安排好

前边我们报导过&#xff0c;PHP 兼 Zend 公司联合创始人 Zeev Suraski 宣布目前已经从工作了 20 年的 Zend 公司离职。2 日晚间&#xff0c;知名 PHP 开发者&#xff0c;同时也是 PHP JIT 主力鸟哥&#xff08;惠新宸&#xff09;在朋友圈中曝出猛料&#xff1a;原来一切都是安…

梯度下降:求线性回归

梯度下降的直线拟合 实现说明 给定若干个x,yx, yx,y并且求得一个最佳的yaxby ax byaxb&#xff0c;也就是二元一次方程组的解。 先放上给定的散点&#xff0c;以及求得的线性回归的直线的图片。 我个人认为&#xff0c;这里的梯度优化&#xff0c;就是通过一个关键式子los…

3分钟了解数据库事务

事务是由几个读取和修改数据的sql命令组成的&#xff0c;但是知道commit命令被执行之后&#xff0c;修改操作才被认为是正常的完成。显式事务常以Begin tran语句开头&#xff0c;以commit tran或者rollback tran语句结尾的。事务具有acid属性原子性&#xff08;atomicity&#…

WebClient, HttpClient, HttpWebRequest ,RestSharp之间的区别与抉择

NETCore提供了三种不同类型用于生产的REST API&#xff1a; HttpWebRequest;WebClient;HttpClient&#xff0c;开源社区创建了另一个名为RestSharp的库。如此多的http库&#xff0c;该怎样选择呢&#xff1f;01HttpWebRequest这是.NET创建者最初开发用于使用HTTP请求的标准类。…

.NetCore 2.1以后的HttpClient最佳实践

ASP.NET Core 2.1中出现一个新的HttpClientFactory功能&#xff0c;它有助于解决开发人员在使用HttpClient实例从其应用程序发出外部Web请求时可能遇到的一些常见问题。01介绍在.NETCore平台的2.1新增了HttpClientFactory&#xff0c;虽然HttpClient这个类实现了disposable&…

点分治(简要讲解 + 模板)

树上点分治 思想 两个点之间的距离无非就是两种关系&#xff1a;我们约定dis[i]dis[i]dis[i]表示这个点到当前根节点的距离 dis[u]dis[v]dis[u] dis[v]dis[u]dis[v]&#xff0c;在同一个根节点的不同子树上。dis[u]dis[v]dis[u] dis[v]dis[u]dis[v]&#xff0c;在同一个棵子…

在 alpine 中使用 NPOI

在 alpine 中使用 NPOIIntro在 .net 中常使用 NPOI 来做 Excel 的导入导出&#xff0c;NPOI 从 2.4.0 版本开始支持 .netstandard2.0&#xff0c;在 dotnet core 应用也可以用 DotNetCore.NPOI。对于 .NET Core 应用来说&#xff0c;如果没有特殊的需求&#xff0c;alpine 是最…

Educational Codeforces Round 16 C. Magic Odd Square 矩阵构造

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 给你一个奇数nnn&#xff0c;让你构造一个n∗nn*nn∗n的矩阵&#xff0c;矩阵的每个位置依次填上[1,n∗n]之内的数[1,n*n]之内的数[1,n∗n]之内的数&#xff0c;满足每行、每列、以及主对角线的和都是奇数。…

关于WCF、WebAPI、WebService之间的区别总结 分布式通信技术

早在1996年Gartner就前瞻性地提出了面向服务架构的思想(SOA)&#xff0c;SOA 的走红在很大程度上归功于 Web Service 标准的成熟和应用的普及。Service Oriented Ambiguity 中文一般理解为&#xff1a;面向服务架构&#xff0c;简称SOA&#xff0c;这个概念算得上微服务的鼻祖了…

.NET中的值类型与引用类型

.NET中的值类型与引用类型这是一个常见面试题&#xff0c;值类型(Value Type)和引用类型(Reference Type)有什么区别&#xff1f;他们性能方面有什么区别&#xff1f;TL;DR&#xff08;先看结论&#xff09;值类型引用类型创建位置栈托管堆赋值时复制值复制引用动态内存分配无需…

跨语言调用Hangfire定时作业服务

背景Hangfire允许您以非常简单但可靠的方式执行后台定时任务的工作。内置对任务的可视化操作。非常方便。但令人遗憾的是普遍都是业务代码和hagnfire服务本身聚合在一个程序中运行&#xff0c;极大的限制了hangfire的扩展和跨语言调用。所以萌生了开发一个支持restful api调用的…

可落地微服务on k8s的持续集成/部署方案

我们隔一流的软件生产工艺还有多远&#xff1f;在距离15000公里外&#xff0c;Amazon一年可以进行5000万次部署&#xff0c;在这一边某电商平台的研发部门里&#xff0c;让他们引以为傲的是他们正在进行“敏捷”开发模式&#xff0c;并对外号称他们是以每周为迭代来进行升级。时…

Codeforces Round #579 (Div. 3) F1. Complete the Projects (easy version) 排序 + 贪心

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 思路&#xff1a; 比较直观的想法就是对于bi≥0b_i\ge0bi​≥0的项目&#xff0c;我们将aia_iai​从小到大排序&#xff0c;让后依次加bib_ibi​&#xff0c;如果有取不到的&#xff0c;显然就无解。否则再看…

历久弥新 - 微软万亿市值背后的文化支撑(下)|DevOps案例研究

内容来源&#xff1a;DevOps案例深度研究-Microsoft文化支撑研究战队&#xff08;本文只展示部分PPT研究成果&#xff0c;更多细节请关注案例分享会&#xff0c;及本公众号。&#xff09;本案例内容贡献者&#xff1a;陈飞&#xff08;Topic Leader&#xff09;、陈雨卿、郭子奇…

架构杂谈《九》

微服务与轻量级通信机制微服务架构是一种架构模式&#xff0c;它提倡将单一应用程序划分成一组小的服务&#xff0c;服务之间胡亮协调、互相配合&#xff0c;为用户提供最终价值。在微服务架构中&#xff0c;服务与服务之间通信时&#xff0c;通常是通过轻量级的通信机制&#…

Codeforces Round #585 (Div. 2) E. Marbles 状压dp + 逆序对

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 思路&#xff1a; 考虑数列最终的状态一定是相同颜色在一起&#xff0c;所以我们发现他的颜色是有顺序的&#xff01;显然可以用状压dpdpdp来枚举颜色的顺序&#xff0c;但是又有问题了&#xff0c;你怎么确…