ASP.NET Core Web Api之JWT VS Session VS Cookie(二)

本文我们来探讨下JWT VS Session的问题,我们可直接抛出问题:使用客户端存储的JWT比服务端维持Session更好吗? 


既然要比较JWT VS Session,那我们就得知道为何需要JWT和Session,它们共同是为了解决什么问题呢?那我们从一个场景说起,网上购物现已是再平常不过的事情了,当我们将某个商品加入购物车后,然后跳转到其他商品页面此时需要之前选择的商品依然在购物车中,此时就需要维持会话,因为HTTP无状态,所以JWT和Session共同点都是为了持久维持会话而存在,为了克服HTTP无状态的情况,JWT和Session分别是如何处理的呢?


640?wx_fmt=gif

JWT VS Session

Session:当用户在应用系统中登录后,此时服务端会创建一个Session(我们也称作为会话),然后SessionId会保存到用户的Cookie中,只要用户是登录状态,对于每个请求,在Cookie中的SessionId都会发送到服务端,然后服务端会将保存在内存中的SessionId和Cookie中的SessionId进行比较来认证用户的身份并响应。


JWT:当用户在应用系统中登录后,此时服务端会创建一个JWT,并将JWT发送到客户端,客户端存储JWT(一般是在Local Storage中)同时在每个请求头即Authorization中包含JWT,对于每个请求,服务端都会进行验证JWT是否合法,直接在服务端本地进行验证,比如颁发者,受理者等等,以致于无需发出网络请求或与数据库交互,这种方式可能比使用Session更快,从而加快响应性能,降低服务器和数据库服务器负载。


通过如上对JWT认证和Session认证简短的描述,我们知道二者最大的不同在于Session是存储在服务端,而JWT存储在客户端。服务端存储会话无外乎两种,一种是将会话标识符存储在数据库,一种是存储在内存中维持会话,我想大多数情况下都是基于内存来维持会话,但是这会带来一定的问题,如果系统存在大流量,也就是说若有大量用户访问系统,此时使用基于内存维持的会话则限制了水平扩展,但对基于Token的认证则不存在这样的问题,同时Cookie一般也只适用于单域或子域,如果对于跨域,假如是第三方Cookie,浏览器可能会禁用Cookie,所以也受浏览器限制,但对Token认证来说不是问题,因为其保存在请求头中。


如果我们将会话转移到客户端,也就是说使用Token认证,此时将解除会话对服务端的依赖,同时也可水平扩展,不受浏览器限制,但是与此同时也会带来一定的问题,一是令牌的传输安全性,对于令牌传输安全性我们可使用HTTPS加密通道来解决,二是与存储在Cookie中的SessionId相比,JWT显然要大很多,因为JWT中还包含用户信息,所以为了解决这个问题,我们尽量确保JWT中只包含必要的信息(大多数情况下只包含sub以及其他重要信息),对于敏感信息我们也应该省略掉从而防止XSS攻击。JWT的核心在于声明,声明在JWT中是JSON数据,也就是说我们可以在JWT中嵌入用户信息,从而减少数据库负载。所以综上所述JWT解决了其他会话存在的问题或缺点:

更灵活、更安全、减少数据库往返,从而实现水平可伸缩、防篡改客户端声明、移动设备上能更好工作、适用于阻止Cookie的用户

640?wx_fmt=gif

综上关于JWT在有效期内没有强制使其无效的能力而完全否定JWT的好处显然站不住脚,当然不可辩驳的是若是没有如上诸多使用限制,实现其他类型的身份验证完全也是合情合理且合法的,需综合权衡,而非一家之言下死结论。到目前为止,我们一直讨论的是JWT VS Session认证,而不是JWT VS Cookie认证,但是如标题我们将Cookie也纳入了,只是想让学习者别搞混了,因为JWT VS Cookie认证这种说法是错误的,Cookie只是一种存储和传输信息介质,只能说我们可以通过Cookie存储和传输JWT。接下来我们来实现Cookie存储和传输JWT令牌。

640?wx_fmt=gif

JWT AS Cookies Identity Claim

在Startup中我们可以添加如下Cookie认证中间件,此时我们有必要了解下配置Cookie的一些选项,通过对这些选项的配置来告知Cookie身份认证中间件在浏览器中的表现形式,我们看下几个涉及到安全的选项。

640?wx_fmt=png

配置HttpOnly标志着Cookie是否仅供服务端使用,而不能通过前端直接访问。


配置SecurePolicy将限制Cookie为HTTPS,在生产环境建议配置此参数同时支持HTTPS。


配置SameSite用来指示浏览器是否可以将Cookie与跨站点请求一同使用,若是对于OAuth身份认证,可设置为Lax,允许外部链接重定向发出比如POST请求而维持会话,若是Cookie认证,设置为Restrict,因为Cookie认证只适用于单站点,若是设置为None,则不会设置Cookie Header值。(注意:SameSite属性在谷歌、火狐浏览器均已实现,对于IE11好像不支持,Safari从版本12.1开始支持该属性)

640?wx_fmt=gif


在创建.NET Core默认Web应用程序时,在ConfigureServices方法中,通过中间件直接配置了全局Cookie策略,如下:

640?wx_fmt=png

当然默认配置了全局Cookie策略,同时也在Configure方法中使用其策略如下:

640?wx_fmt=png

我们也可以直接在上述调用使用Cookie策略中间件的方法中来设置对应参数策略,如下:

640?wx_fmt=png

若是我们在添加Cookie中间件的同时也配置全局Cookie策略,我们会发现对于属性HTTPOnly和SameSite都可配置,此时个人猜测会存在覆盖的情况,如下:

640?wx_fmt=png

对于需要认证的控制器我们需要添加上[Authroize]特性,对每一个控制器我们都得添加这样一个特性,相信大部分童鞋都是这么干的。其实我们大可反向操作,对于无需认证的我们添加可匿名访问特性即可,而需要认证的控制器我们进行全局配置认证过滤器,如下:

640?wx_fmt=png


好了到了这里,我们只是粗略的讲解了下关于Cookie中间件参数配置和Cookie全局配置策略的说明,没有太深入去研究里面的细枝末节,等遇到问题再具体分析吧。继续回到话题,Cookie认证相比JWT对API访问来讲安全系数低,所以我们完全可以在Cookie认证中结合JWT来使用。具体我们可尝试怎么搞呢?将其放到身份信息声明中,我想应该是可行的方式,我们来模拟登陆和登出试试,大概代码如下:

640?wx_fmt=png

640?wx_fmt=png

上述代码很简单,无需我再多讲,和Cookie认证无异,只是我们在声明中添加了access_token来提高安全性,接下来我们自定义一个Action过滤器特性,并将此特性应用于Action方法,如下:

640?wx_fmt=png

640?wx_fmt=png

640?wx_fmt=gif

JWT Combine Cookie Authentication

如上是采用将JWT放到声明的做法,我想这么做也未尝不可,至少我没找到这么做有什么不妥当的地方。我们也可以将Cookie认证和JWT认证进行混合使用,只不过是在上一节的基础上添加了Cookie中间件罢了,如下图:

640?wx_fmt=png

通过如上配置后我们就可以将Cookie和JWT认证来组合使用了,比如我们在用户登录后,如下图点击登录后显示当前登录用户名,然后点击退出,在退出Action方法上我们添加组合特性:

640?wx_fmt=png

640?wx_fmt=png

640?wx_fmt=png

在上一节中,我们通过获取AccessToken,从而访问端口号为5001的客户端来获取当前时间,那现在我们针对获取当前时间的方法添加上需要Cookie认证,如下:

640?wx_fmt=png

640?wx_fmt=png

640?wx_fmt=gif

Cookie认证撤销

在.NET Core 2.1版本通过Cookie进行认证中,当用户与应用程序进行交互修改了信息,需要在cookie的整个生命周期,也就说在注销或cookie过期之前看不到信息的更改时,我们可通过cookie的身份认证事件【撤销身份】来实现这样的需求,下面我们来看看。

640?wx_fmt=png

我们通过重写CookieAuthenticationEvents事件中的ValidatePrincipal,然后判断写在内存中关于用户表示是否存在,若存在则调用 context.RejectPrincipal() 撤销用户身份。然后我们在添加Cookie中间件里配置该事件类型以及对其进行注册:

640?wx_fmt=png

640?wx_fmt=png

接下来我们写一个在页面上点击【修改信息】的方法,并在内存中设置撤销指定用户,如下:

640?wx_fmt=png

640?wx_fmt=gif

从如上动图中我们可以看到,当点击修改信息后,然后将撤销的用户标识写入到内存中,然后跳转到Index页面,此时调用我们写的撤销事件,最终重定向到登录页,且此时用户cookie仍未过期,所以我们能够在左上角看到用户名,不清楚这种场景在什么情况下才会用到。


640?wx_fmt=gif

跳转至登录携带或移除参数

当我们在某个页面进行操作时,若此时Token或Cookie过期了,此时则会自动引导用户且将用户当前访问的URL携带并重定向跳转到登录页进行登录,比如关于博客园如下跳转URL:

640?wx_fmt=png

但是如果我们有这样的业务场景:用于跳转至登录页时,在URL上需要携带额外的参数,我们需要获取此业务参数才能进行对应业务处理,那么此时我们应该如何做呢?我们依然是重写CookieAuthenticationEvents事件中的RedrectToLogin方法,如下:

640?wx_fmt=png

这里需要注意的是因为上述我们用到了IActionContextAccessor,所以我们需要将其进行对应如下注册:

640?wx_fmt=png

最终我们跳转到登录页将会看到我们添加的额外参数id也将呈现在url上,如下:

640?wx_fmt=png

本节我们讲解了Session和JWT的优缺点以及Cookie认证中可能我们需要用到的地方,下一节也是JWT最后一节内容,我们讲讲并探讨如何实现刷新Token,感谢阅读

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

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

相关文章

P4721 【模板】分治 FFT

传送门 文章目录题意:思路:题意: 思路: 写一下式子,发现每个fif_ifi​只有左边的fff对他有影响,所以考虑分治FFTFFTFFT来解决这个问题。 先递归左边,让后计算对右边贡献,再递归右边…

对称迷宫

描述 wlxsq有一个N*NN∗N的网格迷宫,每一个网格都有一个字母编号。 他要从左上角(1,1)(1,1)出发,走到右下角(n,n)(n,n),由于wlxsq很懒,所以他每次只会往右或者往下走一格。 由于最后到终点的路径方案太多太多了,所以…

程序员生活之路--来自程序员爸爸的一封信

亲爱的孩子:当你看到爸爸这封信的时候,说明你已经长大了或者已经会玩微信公众号了,当然爸爸还是希望你长大了,并不希望你那么小就天天抱着手机刷微信。我写这个文章的时候正直盛夏,现在外边正是37度的高温,…

C#上位机与欧姆龙PLC的通信05---- HostLink协议

1、介绍 Hostlink协议是欧姆龙PLC与上位机链接的公开协议。上位机通过发送Hostlink命令,可以对PLC进行I/O读写、可以对PLC进行I/O读写、改变操作模式、强制置位/复位等操作。由于是公开协议,即便是非欧姆龙的上位设备(软件)&…

Codeforces Round #737 (Div. 2) D. Ezzat and Grid 线段树动态开点

传送门 文章目录题意:思路:题意: 思路: 比较套路的一个题,我们维护一个dp[i]dp[i]dp[i]表示到了第iii行能保留的区间最多是多少。 转移比较明显:dp[i]max(dp[j])dp[i]max(dp[j])dp[i]max(dp[j]) 其中jjj能…

从零开始实现ASP.NET Core MVC的插件式开发(三) - 如何在运行时启用组件

标题:从零开始实现ASP.NET Core MVC的插件式开发(三) - 如何在运行时启用组件 作者:Lamond Lu地址:https://www.cnblogs.com/lwqlun/p/11260750.html源代码:https://github.com/lamondlu/DynamicPlugins前情回顾•从零开始实现ASP…

笔记,Vector类模板的基本功能

有基本的查找&#xff0c;排序&#xff0c;插入&#xff0c;删除区间&#xff0c;扩容&#xff0c;减容等 放在博客上主要是为了以后学习方便查找一些&#xff0c;实际上并没有上面参考价值&#xff0c;许多STL模板中有的东西我这并没有。 #include <bits/stdc.h> using…

SP1043 GSS1 - Can you answer these queries I 猫树

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 思路&#xff1a; 猫树是一种可以O(nlogn)O(nlogn)O(nlogn)预处理&#xff0c;O(1)O(1)O(1)查询的数据结构。预处理的信息应该满足可合并的性质&#xff0c;与线段树pushuppushuppushup的原理相同&#xff0…

.NET Core 3.0之深入源码理解HttpClientFactory(二)

写在前面上一篇文章讨论了通过在ConfigureServices中调用services.AddHttpClient()方法&#xff0c;并基于此进一步探讨了DefaultHttpClientFactory是如何创建HttpClient实例和HttpMessageHandler实例的&#xff0c;并了解了DefaultHttpClientFactory内部维护者一个定时器和两个…

链表的顺序存储

链表的顺序存储无非就是在一个结构体数组里面集成了许多函数的操作&#xff0c;使之算法变得更加简单。 #include<stdio.h> #include<windows.h> #define maxsize 100 typedef int datatype; typedef struct {datatype a[maxsize];int size; }sequence_list;void …

2021牛客暑期多校训练营6 Hopping Rabbit 扫描线 + 矩形 + 细节

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 给你nnn个矩形&#xff0c;以及一个距离ddd&#xff0c;让你找一个点(x0.5,y0.5)(x0.5,y0.5)(x0.5,y0.5)&#xff0c;这个点一次能向四个方向跳ddd的距离&#xff0c;这个点不管怎么跳都跳不到矩形内。输出(…

动手造轮子:基于 Redis 实现 EventBus

动手造轮子&#xff1a;基于 Redis 实现 EventBusIntro上次我们造了一个简单的基于内存的 EventBus&#xff0c;但是如果要跨系统的话就不合适了&#xff0c;所以有了这篇基于 Redis 的 EventBus 探索。本文的实现是基于 StackExchange.Redis 来实现。RedisEventStore 实现既然…

最小生成树KrusKal算法(并查集)

洛谷p1111链接 克鲁斯卡尔算法的思路就是由森林变成树的过程&#xff0c;其中最主要的就是贪心和并查集的应用。 我们知道链接n个点需要n-1条边&#xff0c;这就满足的最后生成的是一颗树&#xff0c;而不是一个环。在这n-1条边的选择上我们又要尽可能的让边的权重小&#xff0…

#6278. 数列分块 2 分块 + 块内二分

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 思路&#xff1a; 真 调一晚上血压上来了。 考虑第一个操作&#xff0c;块内打个标记&#xff0c;其他的暴力查询即可。 考虑第二个操作&#xff0c;讲块内元素排序之后&#xff0c;直接二分查询。 注意修改…

使用腾讯云提供的针对Nuget包管理器的缓存加速服务

继阿里巴巴开源镜像站&#xff08;https://opsx.alibaba.com/&#xff09;、华为云镜像站点&#xff08;https://mirrors.huaweicloud.com/ &#xff09;之后&#xff0c;腾讯也已于近日上线了类似的服务&#xff0c;官方名称为腾讯云软件源&#xff08;Tencent Open Source Mi…

最小生成树Prime算法

洛谷p1546链接 Prime算法的核心也是贪心&#xff0c;但是不同的就是&#xff0c;它是一直维护一颗树&#xff0c; 直到变成一颗最小生成树&#xff0c; #include<bits/stdc.h> using namespace std; const int maxn 110; const int inf 0x3f3f3f3f; int maze[maxn][m…

#6284. 数列分块 8 分块

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 思路&#xff1a; 乍一看貌似没有什么东西能维护块内同一个数的个数&#xff0c;但是通过第六感可以发现每次操作后区间都会被推成一个数&#xff0c;那么我们分个块&#xff0c;让后块内打个标记&#xff0…

最短路弗洛伊德(Floyd)算法加保存路径

弗洛伊德算法大致有点像dp的推导 dp[i][j] min(dp[i][k] dp[k][j], dp[i][j]), 其中 i 是起始点&#xff0c;j 是终止点。k是它们经过的中途点。 通过这个公式不断地更新dp[i][j],得到最短路径长。 我们先定义两个矩阵&#xff0c;minpath[i][j],表示的是从 i 到 j 当前得到的…

云考古 | Azure 自建 RDS 让 iPad 跑 Office 97

导语苹果一直在尝试把iPad做成电脑&#xff0c;但效果始终不如真正的PC理想。如果能在iPad上运行PC软件&#xff0c;如完整版的Office&#xff0c;那一定是一种非常理想的方式。我小时候电脑启蒙使用的第一个软件就是Office 97里的Word&#xff0c;这也是第一款引入Office助手&…

P3338 [ZJOI2014]力 FFT + 推式子

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 思路&#xff1a; 这个式子看起来很FFTFFTFFT&#xff0c;让我们来化简一下。 考虑EEE中直接将qiq_iqi​约掉&#xff0c;所以Ei∑j1i−1qj(i−j)2−∑ji1nqj(i−j)2E_i\sum_{j1}^{i-1}\frac{q_j}{(i-j)^2}-…