目录

一、为什么不用Session用JWT

二、JWT结构

三、JWT实现登陆的流程

四、ASP.NET Core对于JWT的封装

五、[Authorize]的注意事项

六、解决JWT无法提前撤回的难题


一、为什么不用Session用JWT

Session在用户登陆验证成功后,服务器端生成唯一标识SessionId,服务器端不仅会把SessionId返回给浏览器端,还会把SessionId和登陆用户的信息的对应关系保存到服务器的内存中;当浏览器端再次向服务器端发送请求的时候,浏览器端就在HTTP请求中携带SessionId,服务器端就可以根据SessionId从服务器的内存中取到用户的信息,这样就实现了用户登陆的功能。

我们一般把SessionId保存在Cookie中,而Session的数据默认是保存在服务器内存中,对于分布式集群环境,Session数据保存在服务器内存中就不合适了,应该保存到一个供所有集群实例访问的共用的状态服务器上。

Session缺点

1、如果Session 数据保存到内存中,当登录用户量很大的时候,Session 数据就会占用非常多的内存,而且无法支持分布式集群环境。
2、如果Session数据保存到 Redis 等状态服务器中,它可以支持分布式集群环境,但是每遇到一次客户端请求都要向状态服务器获取一次 Session 数据,这会导致请求的响应速度变慢。特别是对于一些跨多数据中心的分布式环境,跨数据中心的状态传递更是一件棘手的事情。

在现在的项目开发中,我们倾向于采用JWT代替 Session 实现登录。JWT 是使用JSON格式来保存令牌信息的。JWT 机制不是把用户的登录信息保存在服务器端,而是把登录信息(也叫作令牌)保存在客户端。为了防止客户端的数据造假,保存在客户端的令牌经过了签名处理,而签名的密钥只有服务器端才知道,每次服务器端收到客户端提交的令牌的时候都要检查一下签名,如果发现数据被篡改,则拒绝接收客户端提交的令牌。

二、JWT结构

头部:保存加密算法的说明

负载:保存的是用户的ID、用户名、角色等信息

签名:根据头部和负载一起算出来的值

三、JWT实现登陆的流程

1、客户端向服务器端发送用户名、密码等请求登录。

2、服务器端校验用户名、密码,如果校验成功,则从数据库中取出这个用户的ID、角色等用户相关信息。

3、服务器端采用只有服务器才知道的密钥来对用户信息的JSON字符串进行签名,形成签名数据。

4、服务器端把用户信息的JSON字符串和签名拼接到一起形成JWT,然后发送给客户端。

5、客户端保存服务器端返回的JWT,并且在客户端每次向服务器端发送请求的时候都带上这个JWT。

6、每次服务器端收到浏览器请求中携带的JWT后,服务器端用密钥对JWT的签名进行校验,如果校验成功,服务器端则从JWT中的JSON字符串中读取用户的信息。这样服务器端就知道这个请求对应的用户了,也就实现了登陆的功能。

四、ASP.NET Core对于JWT的封装

第一步:配置系统中配置一个名字叫JWT的节点,在节点下创建SigningKey、ExpireSeconds两个配置项,分别代表JWT的密钥和过期时间。我们再创建一个对应JWT节点的配置类JWTOptions,类中包含SigningKey、ExpireSeconds两个属性。

第二步:NuGet引用程序集Microsoft.AspNetCore.Authentication.JwtBearer包

第三部:编写配置,放到Program.cs的builder.Build之前

第四步:在Program.cs的app.UseAuthorization之前添加app.UseAuthentication

第五步:在TextController类中增加登陆并且创建JWT的操作方法Login

第六步:在需要登陆才能访问的控制器类上添加[Authorize]这个ASP.NET Core内置的Attribute

五、[Authorize]的注意事项

[Authorizel这个Attribute既可以被添加到控制器类上,也可以被添加到操作方法上。我们可以在控制器类上标注[Authorize],那么这个控制器类中的所有操作方法都会被进行身份验证和授权验证:对于标注了[Authorize]的控制器类,如果其中某个操作方法不想被验证,我们可以在这个操作方法上添加[AllowAnonymous]。如果没有在控制器类上标注[Authorize],那么这个控制器类中的所有操作方法都允许被自由地访问:对于没有标注[Authorize]的控制器类,如果其中某个操作方法需要被验证,我们也可以在操作方法上添加[Authorize]。

六、解决JWT无法提前撤回的难题

JWT 把用户信息保存到客户端,而不像 Session 那样在服务器端保存状态,因此更加适合分布式系统及前后端分离项目,但是任何技术都不是完美的,JWT 的缺点是:一旦JWT 被发放给客户端,在有效期内这个令牌就一直有效,令牌是无法被提前撤回的。哪些场景会需要在JWT过期之间提前撤回令牌呢?比如,用户被删除了,那么针对这个用户的令牌就要被撤回,否则会出现客户端使用已经被删除的用户身份的问题:再如,某个JWT 被恶意攻击者拿到并用来发送恶意请求,我们也要撤回针对这个用户的令牌,以便阻断攻击者: 再如,用户在 A设备上登录了,稍后又在 B 设备上登录了,我们就需要把用户在 A 设备上登录获得的JWT 撤回,否则就会出现用户同时在多个设备上登录的问题。上面提到的这些需求其实用传统的 Session 实现更合适

思路:在用户表中增加一个整数类型的列 JWTVersion,它代表最后次发放出去的今牌的版本号:每次登录、发放令牌的时候,我们都让JWTVersion 的值自增同时将JWTVersion 的值也放到JWT 的负载中:当执行用用户、撤回用户的令牌等操作的时候,我们让这个用户对应的JWTVersion的值自增:当服务器端收到客户端提交的JWT 后,把JWT 中的JWTVersion 值和数据中的JWTVersion 值做比较,如果JWT中JWTVersion的值小于数据库中JWTVersion 的值,就说明这个JWT 过期了,这样我们就实现了JWT 的撤回机制。由于我们在用户表中保存了JWTVersion 值,因此这种方案本质上仍然是在服务器端保存状态,这是绕不过去的,只不过这种方案是一种缺点比较少的妥协方案。

代替Session的JWT相关推荐

  1. 什么是 Cookie Session 和 JWT

    无状态 Q: 大家都知道HTTP是无状态的协议, 那怎么理解无状态呢? A: 想象一下你们公司有个看门的门卫, 记性特别差, 还是个脸盲, 但是特别有职业操守, 每次出门回来都管你要出入证; 有一次, ...

  2. 转载:Session与JWT的使用

    登录认证,估计是所有系统中最常见的功能了,并且也是最基础.最重要的功能.为了做好这一块而诞生了许多安全框架,比如最常见的Shiro.Spring Security等. 本文是一个系列文章,最终的目的是 ...

  3. 快速了解会话管理三剑客cookie、session和JWT

    更多内容,欢迎关注微信公众号:全菜工程师小辉.公众号回复关键词,领取免费学习资料. 存储位置 三者都是应用在web中对http无状态协议的补充,达到状态保持的目的 cookie:cookie中的信息是 ...

  4. 【JavaWeb】认证授权(一)—— Session、JWT

    文章目录 1.基础知识 2.实现 2.1Session 2.1.1基本实现 2.1.2添加过滤器 2.1.3上下文对象 2.2JWT 2.2.1基本实现 2.2.2添加拦截器 2.2.3上下文对象 1 ...

  5. 熬夜彻底搞懂Cookie Session Token JWT

    一切的根源就是因为 HTTP 是一个无状态的协议. HTTP 是一个无状态的协议 什么是无状态呢?就是说这一次请求和上一次请求是没有任何关系的,互不认识的,没有关联的. 看过电影<夏洛特烦恼&g ...

  6. 彻底搞懂Cookie、Session、JWT和Token

    文章目录 引入:http是一个无状态协议?怎么解决呢? 一.Cookie和Session 1.1 cookie 注意事项: 1.2 cookie 重要的属性 1.3 session 注意事项: 1.4 ...

  7. jwt 如何实现踢人,session 和 jwt 鉴权的区别

    Session流程: 1.登录 2.服务端产生session并保存在内存中,并向客户端写入sessionId 3.客户端请求,带上cookie中的sessionId 4.客户端根据sessionId ...

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

    本文我们来探讨下JWT VS Session的问题,我们可直接抛出问题:使用客户端存储的JWT比服务端维持Session更好吗? 既然要比较JWT VS Session,那我们就得知道为何需要JWT和 ...

  9. JWT和Session的区别

    session.token与jwt 自认为对session.token与jwt理解还可以,这次来讲讲这个话题. session与cookie 什么是session session翻译过来是会话,但在W ...

最新文章

  1. 008_TreeSet使用Comparator排序
  2. 数字三角形,最长上升子序列,背包模型 AcWing算法提高课 (详解)
  3. webase crud查看所有表_Laravel-Gii 可视化代码生成工具 CRUD +GUI
  4. 吴恩达:机器学习应以数据为中心
  5. 的优缺点_折叠门的优缺点
  6. 1090. Highest Price in Supply Chain (25) dfs
  7. 面试时被问如何进行接口测试怎么回答
  8. Javascript第六章JavaScript字面量加数组创建对象第三课
  9. 中国农田生产潜力数据集
  10. 使用keeplive处理socket网络异常断开
  11. Alfred插件之有道翻译配置过程
  12. 如何使用一个手机号注册两个微信号!
  13. 兰大《银行会计学》命题作业离线作业
  14. 数据的更新(update的用法)笔记
  15. Mac 解决终端:-bash: /Users/xxx/.profile: No such file or directory
  16. 泊松分布(Poisson Distribution)
  17. MDX示例:求解中位数、四分位数(median、quartile)
  18. 使用超级表格快速创建在线表单(如问卷调查、报名表)
  19. 【学习笔记15】JavaScript的函数
  20. 爬虫 | 王者荣耀高清壁纸-单线程

热门文章

  1. awr报告 解读_「awr」AWR报告关于DB Time的解读 - seo实验室
  2. php强制取整,php 取整方法总结_PHP教程
  3. 大数据CDH安装详细教程
  4. 寻找第k大的数的方法总结
  5. SIFT特征提取分析(转载)
  6. iOS在image上画文字
  7. 【LeetCode - 1176】健身计划评估
  8. python matplotlib 实时绘图
  9. UML——医院预约挂号系统(业务模型)
  10. C-字符串函数合集模拟实现介绍注意事项