注:本节涉及到前后端,这个系列的对比学习,还是专注在前端Vue和Blazor技术,所以就不撸码了,下面主要学习概念。

我们知道,Http是无状态协议,客户端请求服务端,认证一次后,如果再次请求,又要重新认证,因为对服务端来说,客户端的每次请求都是无差别的!另外,服务端的授权体系,一般使用基于RBAC角色权限模型。角色信息,我们可以在客户端每次请求都,都查询一次,但这样比较消耗资源。最好的方式,是客户端第一次请求时,就将角色传给客户端,之后客户端每次请求,直接携带角色信息。而这些问题,都需要使用Cookie、Session或者jwt来解决。

1、先说Cookie。下图为Cookie在客户端与服务端的应用逻辑图。

如上图所示:

  • 客户端首次请求服务器时,携带参数(如用户名和密码),服务器根据参数判断是否合法。如合法,则在Response中颁发Cookies,如在.NET中,写入Cookie,【Response.Cookies[“name”].value = “functionMC”;Response.Cookies[“name”].Expires=DateTime.Now.AddDays(1);】,其中Expires属性,为服务端设置的过期时间。
  • 客户端收到服务器的Response后,将Cookie以健值对的方式保存到浏览器中,如使用js直接操作DOM,【document.Cookie="username=John Doe; expires=Thu, 18 Dec 2043 12:00:00 GMT";】,客户端也可以设置过期时间。如不设置,保存在内存中,浏览器关闭时自动清除;如设置,则保存在本地硬盘中,到期后自动清除。
  • 之后,客户端每次访问服务器,都会在请求头中携带相应站点的Cookie。服务端就可以读取Cookie,如在.NET中,读取Cookie,【string name = Request.Cookies[“name”].value】
  • Cookie在安全性方面,易出现Cookie劫持和欺骗,大小和数量方面也受限制。所以在Cookie之后,出现了Session。

2、Session。下图为Session在客户端与服务端的应用逻辑图

如上图所示。

  • 客户端首次访问服务器后,判断是否合法,如果合法,则在服务器的缓存中建立一个键值对,键为SessionID,同时将SessionID作为Cookie返回给客户端。客户端再次请求时,请求头携带SessionID,服务端根据SessionID,查找缓存信息,根据缓存信息进行处理。
  • 使用Session后,客户端与服务端之间只传递SessionID,更多信息在服务端缓存中,这样可以保存更多信息。Session可以设置有效期,也可以不设置。如不设置,则只在当前会话中有效,客户端关闭后就失效,这样也更安全。
  • Session本身的含义,指客户端与服务端之间的会话,背后实质指的是一种服务器缓存,如果请求不是很多,效率还是很高的
  • Session可以有效利用服务端资源,不受客户端限制,安全性更好。但是,当客户端的并发请求比较多时,会很占服务器内存。如果是分布式,不同的Session存储在不同的服务器之间,而客户端每次请求的路径是随配的,要解决分布式,我们就需要在每台服务器之间同步SessionID和缓存信息。最后,SessionID还是依赖于Cookie,Cookie的跨域、单点登陆难等问题,它也一样有。所以,token的方案开始出现,它是目前最主流的方案,而其中最重要的标准,就是jwt。

3、jwt。下图为token/jwt在客户端和服务端的应用逻辑图

如上图所示,jwt重新将信息保存在了客户端,节省了服务端资源,也没有分布式的问题,同时在灵活性和安全性方面有了质的提升。

  • 灵活性方面:不再限于Cookie,可以保存到本地的Storage或IndexedDB,甚至于远程数据库里,更加的自由。同时,它以JSON加密形式保存在客户端的,是跨语言的,原则上任何web形式都支持。
  • 安全性方面:可以说有了质的提升,这才是jwt的核心。首先它可以完全不依赖于Cookie,它没有跨域、单点登陆等问题;其次,它将加密和解密的过程,放在了服务器上,即使信息被截获,也无法篡改。
  • 更好的支持分布式:在Session方案中,我们需要在每个服务器都进行缓存同步。而jwt中,我们只要在每个服务器都拷备一份密钥即可,或者可以将密钥统一保存到一个Redis服务器中,每个服务器统一向Redis请求密钥,这样连拷贝密钥的工作也可省去

下面简单说明一下jwt的构成、生成、加密和解密过程:

  • jwt由Header、Playload和Signature三部分组成,以符号“.”连接成字符串。其中Header是一个json对象的Base64编码,主要有签名的算法信息;Playload也是一个json对象的Base64编码,这是传输的主体内容,比如用户角色、所在部门等信息都可以存放在里面。我们知道Base64不具有加密能力,可以说Header和Playload是明文传输的,在Playload里面,千万不能放敏感信息。而Signature才是jwt安全体系的核心
  • jwt是在服务端生成的,我们定义好Header和Playload后,在服务端我们有一个密钥Secret,这个密钥是一个没有规律的字符串。我们使用Header里的哈希算法,加上密钥、Header和Playload,就可以算出签名Signature。Signature是不可匿的,无法破解,破解也没意义。
  • 客户端再次请求时,服务端获得请求头携带的jwt后,取出Header、Playload、Signature(A)。对Header进行Base64解码,获取其中的哈希算法,然后重新使用这个哈希算法,加上密钥、Header和Playload重新算出一个签名Signature(B),然后比对Signature(A)和Signature(B)是否一致,如果一致,则请求是合法的,服务端放行,并使用Playload中的信息进行计算处理。
  • 服务端的密钥Secret,是计算签名的安全核心,一定要保存好,最好定期更新。

Blazor和Vue对比学习(进阶2.2.4):状态管理之持久化保存(2),Cookie/Session/jwt的更多相关文章

  1. Blazor和Vue对比学习:说在开始前

    1.Vue:现代前端三大框架之一(Vue/React/Angualr),基于HTML.CSS和JavaScript,2014年正式对外发布,目前已发展到3.X版本.值得说道的是,Vue的创始人作者是华 ...

  2. Blazor和Vue对比学习(基础1.4):事件和子传父

    Blazor和Vue的组件事件,都使用事件订阅者模式.相对于上一章的组件属性,需要多绕一个弯,无论Blazor还是Vue,都是入门的第一个难点.要突破这个难点,一是要熟悉事件订阅模式<其实不难& ...

  3. Blazor和Vue对比学习(基础1.6):祖孙传值,联级和注入

    前面章节,我们实现了父子组件之间的数据传递.大多数时候,我们以组件形式来构建页面的区块,会涉及到组件嵌套的问题,一层套一层.这种情况,很大概率需要将祖先的数据,传递给子孙后代去使用.我们当然可以使用父 ...

  4. Blazor和Vue对比学习(进阶2.1.1):生命周期,基本理解和使用

    一.基本理解 首次接触"生命周期"这个名词,是比较晦涩的,Vue中又有生命周期钩子,而Blazor则是虚方法重写,容易蒙.所以,我尝试从初学者的角度来阐述一下. 1.我们在基础部分 ...

  5. Blazor和Vue对比学习(进阶2.2.3):状态管理之状态共享,Blazor的依赖注入和第三方库Fluxor

    Blazor没有提供状态共享的方案,虽然依赖注入可以实现一个全局对象,这个对象可以拥有状态.计算属性.方法等特征,但并不具备响应式.比如,组件A和组件B,都注入了这个全局对象,并引用了全局对象上的数据 ...

  6. Blazor和Vue对比学习(基础1.9):表单输入绑定和验证,VeeValidate和EditFrom

    这是基础部分的最后一章,内容比较简单,算是为基础部分来个HappyEnding.我们分三个部分来学习: 表单输入绑定 Vue的表单验证:VeeValidate Blazor的表单验证:EditForm ...

  7. Blazor和Vue对比学习(基础1.8):Blazor中实现计算属性和数据监听

    1.7章<传递UI片断>,需要做几个案例,这部分暂停消化几天.我们先把基础部分相对简单的最后两章学习了. 计算属性和数据监听是Vue当中的概念,本质上都是监听数据的变化,然后做出响应.两者 ...

  8. Blazor和Vue对比学习(基础1.1):组件结构

    难度:★ 简单说一说: 1.Vue和Blazor都遵循单文件结果,即HTML(视图模板).CSS(样式).JS/C#(代码逻辑)写在一个文件里,Vue的文件后缀为.vue,Blazor的文件后缀为.r ...

  9. Blazor和Vue对比学习(基础1.2):模板语法和Razor语法

    Vue使用模板语法,Blazor使用祖传的Razor语法,从逻辑和方向上看,两者极为相似,比如: 都基于HTML 都通过声明式地将组件实例的状态(数据/方法)绑定到呈现的DOM上 都通过指令实现更加丰 ...

随机推荐

  1. sqlalchemy模块介绍、单表操作、一对多表操作、多对多表操作、flask集成.

    今日内容概要 sqlalchemy介绍和快速使用 单表操作增删查改 一对多 多对多 flask集成 内容详细 1.sqlalchemy介绍和快速使用 # SQLAlchemy是一个基于 Python实 ...

  2. Mac-Typora快捷键

    标题(大钢) command+(1-6)) 如:command+1,设置为一级标题 引用 快捷键:command+option+Q 或者:先">",后面直接加内容 二级引用: ...

  3. Linux常用命令(超详细)

    一.基本命令 1.1 关机和重启 关机 shutdown -h now 立刻关机 shutdown -h 5 5分钟后关机 poweroff 立刻关机 重启 shutdown -r now 立刻重启 ...

  4. ASCII&Base64

    ASCII https://zh.wikipedia.org/wiki/ASCII American Standard Code for Information Interchange,美国信息交换标 ...

  5. 645. Set Mismatch - LeetCode

    Question 645. Set Mismatch Solution 思路: 遍历每个数字,然后将其应该出现的位置上的数字变为其相反数,这样如果我们再变为其相反数之前已经成负数了,说明该数字是重复数 ...

  6. RabbitMQ 环境安装

    每日一句 Wisdom is knowing what to do next, skill is knowing how to do it, and virtue is doing it. 智慧是知道 ...

  7. 第06组 Alpha冲刺 (2/6)

    目录 1.1 基本情况 1.2 冲刺概况汇报 1.郝雷明 2. 方梓涵 3. 黄少丹 4. 董翔云 5.曾丽莉 6. 詹鑫冰 7.鲍凌函 8.杜筱 9.曹兰英 10. 吴沅静 1.3 冲刺成果展示 1 ...

  8. Spring IOC源码研究笔记(2)——ApplicationContext系列

    1. Spring IOC源码研究笔记(2)--ApplicationContext系列 1.1. 继承关系 非web环境下,一般来说常用的就两类ApplicationContext: 配置形式为XM ...

  9. 洛谷 P2629 好消息,坏消息 题解

    暴力算法的时间复杂度是O(n^2),考虑优化: 先导入一种思想--断环为链.说通俗点就是在原数组后面再接上下标为1--(n - 1)的元素: 以样例为例:-3 5 1 2:我们将其断环为链后可以得到这 ...

  10. FFT 小记

    写在前面 \(Q:\) 为什么会心血来潮去学 FFT \(A:\) 当本蒟蒻还在努力消化凸包时:.所以本蒟蒻也来看一下 等等 摸头警告 .思维已经废了 About FFT FFT( \(Fast\ F ...