• Blazor和Vue对比学习(进阶2.2.4):状态管理之持久化保存(2),Cookie/Session/jwt


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

     

    我们知道,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还是依赖于CookieCookie的跨域、单点登陆难等问题,它也一样有。所以,token的方案开始出现,它是目前最主流的方案,而其中最重要的标准,就是jwt

     

     

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

     

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

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

     

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

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

     

  • 相关阅读:
    docker命令大全
    Objective-C网络数据捕获:使用MWFeedParser库下载Stack Overflow示例
    OpenLayers实战,WebGL图层根据Feature要素的变量动态渲染多种颜色的三角形,适用于大量三角形渲染不同颜色
    【C#】WCF和TCP消息通信练习,实现聊天功能
    GBase 8c V3.0.0数据类型——data_part
    卷积计算公式 神经网络,卷积神经网络应用举例
    ROS从入门到精通3-3:Solidworks三维建模并导入Rviz、Gazebo图文教程
    Leetcode 69.x的平方根
    计算机毕业设计springboot基于springboot和vue的音乐网站gk1c4源码+系统+程序+lw文档+部署
    快速实现抖音上下滑动,你不知道的ViewPager2用法,信息量巨大,建议收藏点赞。老tier~
  • 原文地址:https://www.cnblogs.com/functionMC/p/16553775.html