注:本节涉及到前后端,这个系列的对比学习,还是专注在前端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对比学习(基础1.9):表单输入绑定和验证,VeeValidate和EditFrom

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

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

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

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

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

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

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

  9. Blazor和Vue对比学习(基础1.3):属性和父子传值

    组件除了要解决视图层展示.视图层与逻辑层的数据绑定,还需要解决一个重大问题,就是在组件树中实现数据传递,包括了父到子.子到父.祖到孙,以及任意组织之间.而我们上一章讲到的实现双向绑定的两个指令,Vue ...

  10. Blazor和Vue对比学习(基础1.5):双向绑定

    这章我们来学习,现代前端框架中最精彩的一部分,双向绑定.除了掌握原生HTML标签的双向绑定使用,我们还要在一个自定义的组件上,手撸实现双向绑定.双向绑定,是前两章知识点的一个综合运用(父传子.子传父) ...

随机推荐

  1. C# 将多个office文件转换及合并为一个PDF文件

    PDF文件介绍 PDF(Portable Document Format )文件源于20世纪90年代初期,如今早已成为了一种最流行的的文件格式之一.因为PDF文件有很多优点: 支持跨平台和跨设备共享 ...

  2. 深入浅出Mybatis系列(五)---TypeHandler简介及配置(mybatis源码篇)

    上篇文章<深入浅出Mybatis系列(四)---配置详解之typeAliases别名(mybatis源码篇)>为大家介绍了mybatis中别名的使用,以及其源码.本篇将为大家介绍TypeH ...

  3. 06Java数组

    动手动脑: import java.io.*; public class QiPan { //定义一个二维数组来充当棋盘 private String[][] board; //定义棋盘的大小 pri ...

  4. (转)SQLLite数据操作

    原文:http://dreamboy.blog.51cto.com/3180937/722352 SQLLite数据操作 一般数据采用的固定的静态数据类型,而SQLite采用的是动态数据类型,会根据存 ...

  5. 工作中Linux常用命令

    rpm -qa|grep -i mysql rpm -ev mysql-server-5.1.73-5.el6_6.x86_64 如果报: error: Failed dependencies: li ...

  6. 未能加载文件或程序集 Newtonsoft.Json, Version=4.5.0.0 的报错,解决方法

    使用httpclient测试webapi的时候客户端报错: {"未能加载文件或程序集“Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, P ...

  7. print a float number with 3 digits following

    just use the java's printf function. It is like C's printf. System.out.printf("%.3f\n", x) ...

  8. vue学习笔记(一)——why Vue

  9. 洛谷P3806 点分治

    点分治 第一次写点分治..感觉是一个神奇而又暴力的东西orz 点分治大概就是用来处理树上链的信息,把路径分成过点x和不过点x的两种,不过点x的路径可以变成过点x的子树中一点的路径,递归处理 #incl ...

  10. redis 持久化共享 Session

    https://docs.microsoft.com/zh-cn/azure/redis-cache/cache-aspnet-session-state-provider