当前位置: 首页 > 科技观察

关于认证,看懂这篇文章就够了

时间:2023-03-13 17:12:20 科技观察

第一章cookie的诞生及其特点众所周知,web服务器是无状态的,也就是说服务器不知道用户上一次请求做了什么。它们相互独立,客户端信息仅来自于每次请求中携带的或服务器自身保存的公共信息,可供所有请求使用。因此,为了跟踪用户请求的状态信息,比如记录用户网上购物的购物车历史,cookies应运而生。服务器响应客户端请求时,会向客户端推送一个cookie。这个cookie记录了服务器上的一些信息。客户端在后续请求中携带此cookie。服务器可以根据这个cookie来判断请求的上下文。关系。cookies的出现是无状态向有状态过渡的一种手段。以登录为例,用户输入帐号名和密码,向服务器发送请求,服务器生成cookie发送给浏览器,浏览器将cookie保存在目录下某个目录下的文本文件中。k-v的形式,下次请求同一个网站时会向服务器发送cookie。服务器验证接收到的cookie是否与服务器的cookie一致,如果不一致则验证失败。这是最初的想法。浏览器中保存的cookie位于下图所示位置:cookie的原理决定了它具有以下特点:1.保存在客户端,可以随意篡改,不安全.2.其内容将通过http交互传输。影响性能,所以cookie中可以存储的数据不能太大,最大4kb3,一个浏览器最多只能为一个网站存储不超过20个cookie,浏览器一般只允许300个cookie4,移动端对不友好cookiesupport5.一般都是明文存储。对象在存储之前需要被序列化。分析需要反序列化二级域名间的cookie共享。还是以登录cookie为例。比如现在有两个二级域名,http://a.xxx.com(域名A)和http://b.xxx.com(域名B)。那么,域名A的登录cookie是否可以在域名B下使用呢?默认情况下,只有域名A的服务器才能获取到域名A的服务主机中生成的cookie,其他域名无法获取到这个cookie。托管cookie。但是服务器可以通过显式声明cookie的域来定义它的域。上面的例子中,通过Set-Cookie设置域名A的登录cookie的域(domain)为http://xxx.com(他们共同的顶级域名)),设置路径为'/',Set-Cookie:name=value;domain=xxx.com;path='/',那么域名B就可以读取了。在新规范rfc6265中,domain的值忽略了任何前导点,即**xxx.com**和**.xxx.com**都可以在子域中使用。SSO(单点登录)也是基于这个原理实现的。比如现在有两个域名,a.b.e.f.com.cn(域名1)和c.d.e.f.com.cn(域名2),域名2要读取域名1的cookie,域名1可以访问哪些域名宣布?答案是.e.f.com.cn或.f.com.cn,浏览器不能接受domian为.com.cn的cookie,因为如果cookie域名可以设置为后缀,那就是SmashBros.那么如果域名1设置-Cookie:mykey=myvalue1;domain=e.f.com.cn;path='/'域名2套Set-Cookie:mykey=myvalue2;domain=e.f.com.cn;path='/'那么应该是mykey的值域下将被覆盖为myvalue2。很容易理解,在同一个域下,cookie的mykey是唯一的。通常,我们需要通过设置正确的域和路径来减少不必要的数据传输并节省带宽。cookie-session模式原理随着交互式web应用的兴起,cookie大小的限制和浏览器存储cookie数量的限制,我们必须需要更强大的空间来存储大量的用户信息,比如who登录我们的网站,谁在购物车里添加了商品等等,服务器都要保存几千万甚至更多用户的信息,cookies显然是不行的。那我们该怎么办呢?试想一下,我们在服务器端寻找一个空间来存储所有用户会话的状态信息,并为每个用户分配一个不同的“身份”,即sessionId,然后将这个sessionId推送到浏览器客户端进行存储记录cookie中的当前状态,下次请求时只需要携带这个sessionId,服务器就可以到那个空间去搜索这个identifier对应的用户。**这样既可以解决cookie限制问题,又不会将用户信息暴露给客户端,大大增加了实用性和安全性。用户信息存储在哪里?可以直接存到服务器吗?如果存储在服务器中,1.这对服务器来说是一个巨大的开销,严重限制了服务器的扩展能力。2、假设web服务器做了负载均衡,用户user1是通过机器A登录系统的,那么如果下一个请求是转发到另一台机器B上,则用户信息并没有存储在机器B上,所以不能找到sessionId,所以sessionId不应该存储在服务器上。这时候redis/Memcached就出来解决这个问题了,他们可以简单的理解为缓存数据库。当我们将sessionId集中存储在一个独立的缓存服务器上时,所有的机器都会去这个缓存系统根据sessionId获取用户信息和鉴权。那么问题就解决了。Cookie-session工作原理流程图从它的工作原理来看,你有没有发现这个方法有什么问题?即增加了单点登录失败的可能性。如果负责会话的机器挂了,整个登录也会失败。刚挂了但是一般在项目中,负责session的机器也是多机集群,做负载均衡,增加可靠性。思考:如果服务器重启,用户信息会不会丢失?Redis和其他缓存服务器也有一个集群。假设某个服务重启了,它会从其他正在运行的服务器上搜索用户信息。都崩溃了,怎么办?一般的应对策略是,内存中保存的用户信息会周期性的刷新到宿主机硬盘中持久化数据。即使丢失,也只会在重启后的几分钟内丢失用户数据。Cookie-session限制1、依赖cookie,用户可以在浏览器端禁用cookie2、不支持跨端兼容app等3、业务系统不断请求缓存服务器查找用户信息,增加内存开销并给服务器带来太大压力41.服务器是有状态的。如果没有办法对服务器进行缓存,扩容就非常困难。需要在多台服务器疯狂复制sessionId5。存在单点登录失败的可能性。第二章介绍了三种类型的单点登录(singlesign-on)单点登录(SSO),简称单点登录。随着企业的发展,一个大系统可能包含n个多个子系统。用户在操作不同的系统时,需要多次登录,非常麻烦。单点登录就是用来解决这个问题的。在多个应用系统中,您只需登录一次,即可访问其他相互信任的应用系统。前面我们说过,单点登录是基于与顶级域共享的cookie,根据不同的情况可以分为以下三种。1、同一站点下;2、系统在同一顶级域名下;3、每个子系统属于不同的顶级域名。企业一般都有一个顶级域名。前面说了,同一个站点,同一个顶级域网站的单点登录,利用的是cookie顶级域共享的特性。这个过程相信大家都已经了解了,就不赘述了。但是不同的域呢?不同域之间不共享Cookie。我应该怎么办?CAS(CentralAuthenticationService)原理这里我们要说的是CAS(CentralAuthenticationService)过程,这是一个单点登录的标准过程。它使用单独的系统进行认证,以下简称SSO系统。它的过程其实和cookie-session模式是一样的。单点登录意味着每个子系统都有一套完整的cookie-session模式,加上一套cookie-session模式的SSO系统。用户访问系统a,需要登录时跳转到SSO系统,在SSO系统中通过账号密码认证后,SSO服务器保存session,并生成sessionId返回给SSO浏览器,以及浏览器在domain下写入SSOCookie,并生成一个ST,携带ST给系统a,系统a使用这个ST请求SSO系统进行验证,验证成功后,系统a的服务器写入登录status进入会话并在系统域下键入Cookies。之后系统a再次进行登录验证时,会在同一个域下进行验证。此时用户访问系统b,跳转到SSO登录时,发现SSO已经登录了,于是SSO生成一个ST,携带ST给系统b,系统b使用这个ST请求SSO系统进行验证。验证成功后,b系统服务器端将登录状态写入session,并在b系统域下设置cookie。可以看出,在这个过程中,systemb不需要重新登录。关于“跳转到SSO登录,发现SSO已经登录”,如何实现,这里涉及到Oauth2的授权机制,这里就不说了,只是一个简单的思路,就是在系统中btoSSO系统跳转时,让它从系统a跳转,携带系统a的session信息跳转到SSO,再重定向回系统b。关于Oauth2,可以参考阮一峰的《OAuth 2.0 的四种方式》。在第三章中,我们分析了Cookie-session的局限性。有更彻底的解决方案吗?既然SSO认证系统的存在会增加单点故障的可能性,那我们是不是干脆不用它呢?这就是去中心化的思想,就是省略掉用于存储和验证用户信息的缓存服务器,以另一种方式在各自的系统中进行验证。实现方式很简单,就是将所有的session信息加密到cookie中,发送给浏览器,用cpu的计算能力换取空间。JsonWebToken方式服务器不保存sessionId。用户登录系统后,服务器向他发送一个令牌(token)。下次用户再次请求通过Http访问服务器时,通过Httpheader或url带过来token。查看。为了防止他人伪造,我们可以在数据中加入一个只有自己知道的密钥,进行签名,将数据和签名一起作为令牌发送。这样我们就不需要保存token了,因为发送给用户的token中已经包含了用户信息。当用户再次请求时,我使用相同的算法和密钥对令牌中的数据进行加密。如果加密后的结果与token中的签名一致,那么我们就可以进行认证,并从中获取用户。信息。对于服务端来说,这里只负责生成token,然后验证token。不需要额外的缓存服务器来存储大量会话。当面临访问量增加时,我们只需要对访问量大的服务器进行扩容即可。比扩展整个用户中心的服务器更经济。如果有人篡改了用户信息,但是由于不知道密钥,token中的签名和篡改后客户端计算出的签名肯定不一致,认证就会失败,所以安全上不用担心问题。关于token的时效性,是这样处理的。首次登录根据账号密码生成token。对于每个后续请求,服务器更新时间戳并发送新令牌,客户端替换原始令牌。JWT工作原理流程图JWT的优缺点有哪些1.jwt模式的注销其实是一种虚假的登录失败,因为它只是浏览器清除token形成的假象。如果使用之前的token,只要没过期,还是可以登录成功的。2.安全靠密钥,一旦密钥暴露3.加密产生的数据比较长,相对占用流量大。优点1.不依赖cookies,可以跨终端跨程序使用,支持移动设备2.相对无需单点登录的cookie-session方式扩展起来非常容易3.服务端保持无状态特性,并且不需要在服务器或Session中存储用户信息4.单点登录需要不断向SSO站点发送验证请求该模型节省大量请求【小编推荐】HarmonyOS官方战略合作与合作-构建-为什么HarmonyOS技术社区说MQ是互联网架构的解耦神器?普罗米修斯报警规则管理人社部最高法:“996”严重违法!取消“996”,贵公司提上日程了吗?Python硬上C语言,会怎样?CNNIC:我国已成为6G专利申请主要来源国