cookie、ssion和token的概念
Cookie、Session和Token都是为了解决Web⾝份校验⽽产⽣的,这⾥对它们的概念做⼀个简单了解。
Web⾝份校验的发展
很久很久以前,Web基本上就是⽂档的浏览⽽已。既然是浏览,作为服务器,不需要记录谁在某⼀段时间⾥都浏览了什么⽂档,每次请求都是⼀个新的HTTP协
议,就是请求加响应。并不需要记住是谁刚刚发了HTTP请求,每个请求对服务器来说都是全新的。
但是随着交互式Web应⽤的兴起,像在线购物⽹站,需要登陆的⽹站等等,马上就⾯临⼀个问题,那就是要管理会话,必须要记住是哪些⽤户登陆了系统,哪
些⽤户往⾃⼰的购物车中放了商品。意思就是说,服务器必须把每个⽤户区分开,这就是⼀个不⼩的挑战,因为HTTP请求是⽆状态的,于是有⼈就想出了⼀个
办法,这个办法就是给客户端发⼀个会话标识(ssionId,就是⼀个随机的字符串),每个客户端收到的都不⼀样,每次客户端向服务端发起HTTP请求的时
候,就会把这个随机字符串(ssionId)⼀并捎过来,这样就能区分开是哪个⽤户发起的请求了。
这样,服务器就增加了压⼒,因为服务器需要保存所有⽤户的ssionId。如果有上千上万个ssionId,对服务器来说就是⼀个巨⼤的开销,严重地限制了服务
器的扩展能⼒。⽐如说⽤两个机器组成了⼀个集群,⼩明通过机器A登陆了系统,那ssionId就会保存在机器A上,假设⼩明的下⼀次请求被转发到机器B怎么
办?机器B可没有⼩F的ssionId啊。有时候会采⽤ssionsticky的⼩技巧,就是让⼩明的请求⼀直粘连在机器A上。但是这也不管⽤,要是机器A挂掉了,还
得转到机器B上去。
为了解决A机器挂掉的问题,只好做ssionId的复制了,把ssionId在两个机器之间搬来搬去。
再后来,有个叫Memcached的⼩伙⼦⽀了招:把ssionId集中存储到⼀个地⽅,所有的机器都来访问这个地⽅的数据,这样就不⽤复制了。但是这样则增加了
单点失败的可能性,要是那个负责ssion的机器挂了,所有的⽤户都要重新登陆⼀遍,估计得被⼈骂死。
也尝试把这个单点的机器也搞出集群,增加可靠性。但不管如何,这⼩⼩的ssion对服务器来说都是⼀个沉重的负担。
于是,就有⼈提出了摆脱ssion的想法。具体就是不再在服务端保存ssionId了,让客户端去保存⼀个服务端⽣成的token,每次请求的时候附加上这个
token,服务端只要对这个token进⾏相应的校验就可以完成⾝份验证。⽐如说,⼩明已经登陆了系统,服务端给他返回了⼀个令牌(token),⾥⾯包含了⼩明
的urId,下⼀次⼩明再通过HTTP请求访问服务端的时候,就把这个token通过HTTP的Header带过来就可以了。
因为服务端不再存ssionId了,也不会存token,那么就可能会造成有⼼怀不轨的⼈伪造token来做坏事。因此,服务端需要对token做⼀些防伪造的操作,具体
是对数据做⼀个签名。⽐如说⽤HMAC-SHA256算法加上⼀个只有服务器知道的密钥,对数据做⼀个签名,然后把签名和数据⼀起作为token,由于密钥别⼈不
知道,就⽆法伪造token了。
服务器并不会保存这个token,当⼩明再次将token发到服务器的时候,服务端会⽤同样的HMAC-SHA256算法和同样的密钥去对数据再计算⼀次签名,并和
token中的签名做⼀个⽐较,如果相同的话,就可以判断出⼩明已经登陆过,并且可以直接取到⼩明的urId;如果不相同,则数据部分肯定被⼈篡改过,这时
就能够做⼀些⾝份校验失败的相应处理。
token中的数据默认是明⽂保存的(虽然会⽤Ba64URL算法做下编码,但这并不是加密),因此最好不要在其中保存像密码之类的敏感信息。当然了,如果⼀
个⽤户的token被别⼈偷⾛了,服务器并没有办法去辨别,只会认为⼩偷就是合法的⽤户,这其实和⼀个⽤户的ssionId被别⼈偷⾛是⼀样的。
这样⼀来,服务器就不需要保存ssionId了,只需要⽣成token,然后校验token,相当于⽤CPU计算时间换回了存储空间。解决了ssionId这个负担,可以说
是⽆事⼀⾝轻。机器集群现在可以轻松地做⽔平扩展,⽤户访问量增⼤的时候直接加机器就OK。
Cookie
Cookie是⼀个⾮常具体的东西,指的就是浏览器⾥⾯能永久存储的⼀种数据,仅仅是浏览器实现的⼀种数据存储功能。
Cookie是由服务器⽣成,发送给浏览器,浏览器把Cookie以Key-Value的形式保存到某个⽬录下的⽂本⽂件内,下⼀次请求同⼀个⽹站的时候会把该Cookie发
送给服务器。由于Cookie是存在客户端上的,所以浏览器加⼊了⼀些限制确保Cookie不会被恶意使⽤,同时不会占据太多的磁盘空间,每个域的Cookie数量都
是有限的。
Session
Session从字⾯上讲,就是会话。这个就类似于与⼀个⼈交谈,你怎么知道当前和你交谈的是张三⽽不是李四呢?对⽅肯定有某种特征(长相等)表明他就是张
三。Session也是类似的道理,服务器要知道当前发送请求给⾃⼰的是谁。为了做这种区分,服务器就要给每个客户端分配不同的⾝份标识,然后客户端每次向
服务器发送请求的时候,都会带上这个⾝份标识,服务器就会知道这个请求是来⾃于谁了。⾄于客户端怎么保存这个⾝份标识,可以有很多⽅式,对于浏览器客
户端来说⼀般都默认采⽤Cookie的⽅式。
服务器使⽤Session把⽤户的信息临时保存在了服务器上,⽤户离开⽹站之后Session会被销毁。这种⽤户信息存储⽅式相对Cookie来说更加安全,可是Session
有⼀种缺陷,如果Web服务器做了负载均衡,那么下⼀个操作请求到了另⼀台服务器的时候Session就会丢失。
Token
在Web领域基于Token的⾝份验证随处可见。在⼤多数使⽤WebAPI的互联⽹公司中,Token是多⽤户下处理认证的最佳⽅式。⼤部分你见到过的API和Web应
⽤都是使⽤Token,例如Facebook、Twitter、Google+和Github等。
在介绍基于Token的⾝份验证的原理与优势之前,不妨先看看之前的认证都是怎么做的。我们都是知道HTTP协议是⽆状态的,这种⽆状态意味着程序需要验证
每⼀次请求,从⽽辨别客户端的⾝份。在这之前,程序都是通过在服务端存储的登陆信息(Session)来辨别请求的。随着Web应⽤程序以及移动端的兴起,这
种验证⽅式逐渐暴露出了问题,尤其是在可扩展性⽅⾯。
基于服务器验证⽅式暴露的⼀些问题
n:每次认证⽤户发起请求时,服务器需要去创建⼀个记录来存储信息。当越来越多的⽤户发请求时,内存的开销也会不断增加。
2.可扩展性:在服务端的内存中使⽤Session存储登陆信息,伴随⽽来的是可扩展性问题。
(跨域资源共享):当我们需要让数据跨多台移动设备上使⽤的时候,跨域资源的共享就会是⼀个让⼈头疼的问题。在使⽤Ajax抓取另⼀个域的资源,
就可能会出现禁⽌请求的情况。
(跨域请求伪造):⽤户在访问银⾏⽹站时,这种验证⽅式很容易受到跨站请求伪造的攻击,并且能够被利⽤其访问其他的⽹站。
在这些问题中,可扩展性是最突出的,因此我们有必要去寻求⼀种更加⾏之有效的⽅法。
基于Token的验证⽅式
基于Token的⾝份验证是⽆状态的,不将⽤户信息存在服务器或Session中,这种概念就解决了在服务端存储信息时的很多问题。NoSession意味着程序可以根
据需要去增减机器,⽽不⽤去担⼼⽤户是否登陆的问题。基于Token的⾝份验证的过程如下:
1.⽤户通过⽤户名和密码发送请求。
2.程序验证登陆信息,并返回⼀个签名的Token给客户端。
3.客户端存储Token。
4.客户端再次发起HTTP请求,将Token附加在请求中,服务端验证Token并返回数据。
Token的优势
1.⽆状态、可扩展。在客户端存储的Token是⽆状态的,并且能够被扩展。基于这种⽆状态和不存储Session信息,负载均衡器就能够将⽤户信息从⼀个服务传
到其他服务器上。如果我们将已验证的⽤户的信息保存在Session中,则每次请求都需要⽤户向已验证的服务器发送验证信息(称为Session亲和性),在⽤户
量⼤的时候,可能会造成⼀些拥堵(集群中的某⼀台服务器压⼒过⼤)。使⽤Token则不会有这些问题,因为Token不需要依赖特定的服务器。
2.⽀持移动设备。移动设备只需要有存储Token的能⼒,就能够使⽤这种⾝份验证的⽅式。
3.跨程序调⽤。只要⽤户有了⼀个验证通过的Token,数据和资源就能够在任何有相同校验规则的服务器(域)上请求到。
4.安全性较⾼。请求中发送Token⽽不再是发送Cookie,这样就能够防⽌CSRF(跨站请求伪造)。即使在客户端使⽤Cookie存储Token,Cookie也仅仅是⼀个
存储机制⽽不是⽤于认证。不将信息存储在Session中,让我们少了对Session的操作。Token是有时效的,⼀段时间之后⽤户就需要重新验证。同时,Token还
能有撤回的操作,可以通过TokenRevocatation使⼀个特定的Token或⼀组Token失效。
"⼈⽣就像骑单车,要想保持平衡就得始终往前⾛,于是昨天越来越多,明天越来越少。"
本文发布于:2022-11-27 07:10:03,感谢您对本站的认可!
本文链接:http://www.wtabcd.cn/fanwen/fan/90/29521.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |