状态保持的常用手法,原理,以及优劣
首先解释问什么要进行状态保持: ?? ?直接原因: ?? ??? ?http协议是一个无状态的协议: http协议通过socket(套接字)进行通信,客户端连接服务器,一次数据传输完成之后, ?? ??? ?客户端会断开于服务器的连接,服务器也会销毁前一次的连接对象,因此,http协议是一个不能保持状态(无状态)的协议 ?? ??? ? ?? ?需求: ?? ??? ?我们的Web服务器总是希望能够让服务端和客户端彼此认识(保持当前的状态), 从而不至于让用户每跳转一个页面就登陆一次,造成极差的用户体验 ?? ??? ? 手段一: Cookie ?? ?特点 ?? ??? ?cookie是保存在客户端的一个文本文件,一般大小单个文件大小不会超过4kb,只能存非中文和字符串类型,不能存储对象,根据操作系统和浏览器的不同,存储的位置也不尽相同,大体上存放在硬盘或内存中 ?? ?流程:?? ? ?? ??? ?当浏览器向服务器发送请求后,服务器会给客户端发送一些响应信息,其中有一部分会保存在由服务器生成的文本文件(cookie)中, ?? ??? ?保存的信息可以是用户名,id, 浏览记录,历史记录,如果你在登录的时候选择了保存密码,那还会保存你的密码信息(之前有网站就这么干,后来连官网都被黑掉了) ?? ??? ?如果下一次浏览器再一次请求服务器, 就浏览器会在cookie中查找这台服务器域名下的相关信息, 附在请求中,一并发给服务器,服务器就可以解析cookie的信息,然后获知用户的身份,权限等一系列用户信息了 ?? ??? ? ?? ?优缺点: ?? ??? ?这么做优势很明显,即即可以实现状态保持,又不消耗服务器的任何存储资源(cookie存客户端了嘛), 唯一增加的是在请求时多携带了一些数据而已,这些数据小到简直可以忽略不计 ?? ??? ?缺点也很明显: 由于cookie存储在本地,就相当于把网站的很多信息暴露给了有心之人,即使你的cookie信息加了密,那些有心之人也有办法解密,不然你觉得上面的那个网站的官网是怎么被黑掉的, 采用cookie的状态保持手段安全性相对较低 ?? ? 手段二: session ?? ?特点: ?? ??? ?session是基于cookie的, session存储的容量大,可以存储对象,ession存储在服务器端,一般是内存中,或数据库中 ?? ?流程: ?? ??? ?当浏览器向服务器发送请求后,服务器在响应客户端的同时,会在服务器内部保存这个用户的所有登录信息,并存储起来,并根据这个用户的全部信息生成一个针对于这个用户的sessiondi, ?? ??? ?来唯一标识这个用户的所有信息,以形成一种一一对应关系(类似于python中的字典,一键一值的形式), 并把生成的唯一表示sessionid也响应给浏览器,浏览器接收到响应之后,会将sessionid存储在cookie中 ?? ??? ?下一次该用户在请求这台服务器时,浏览器就会把这台服务器下的域名所对应的sessiondi连同请求一并发给服务器,服务器通过sessionid查找到这个用户,并获取用户的相关信息,如果服务器没有获取到sessionid,就说明这个用户并没有在该网站中注册 ?? ??? ?保存用户数据,生成sessionid,并返回就行了, ?? ??? ?但是也会遇到一些问题,如果在浏览器端,cookie被禁用掉了,那必须得有其他的机制来确保sessionid能够准确无误的传回服务器,一般常用的方式是重写url, 这里也分为两种方式: ?? ??? ?一种就是sessionid当做url的附加信息进行传递如http://www.helloword.com/index;sessiondi=83re345#$@@_)*+HJTFV, ?? ??? ?另外一种就是把sessionid当做url的查询参数传递如: http://www.helloword.com/index?sessiondi=83re345#$@@_)*+HJTFV, ?? ??? ?而另一种机制是表单隐藏字段:如果服务器发现客户端禁用掉了cookie,那么服务端就会修改表单,在表单中添加一个隐藏的字段,以保存sessionid,并保证在下一次的请求中,sessionid能被回传给服务器 ?? ?优缺点: ?? ??? ?优点是:安全性提高了,你的用户数据存放在服务器,一般不会被人黑掉,大大提高了数据的安全性 ?? ??? ?缺点是:服务器的存储资源那是相当的宝贵啊,前期用户量少还好说,用户量大了像Facebook,youtube,如果真的使用session的状态保持手段,服务器会被撑爆炸的,太占用服务器存储资源了 ?? ??? ? 手段三: jwt ?? ?特点: ?? ??? ?jwt本身是json类型, 由于json的通用性,jwt也是通用的,跨语言特性很好, jwt本质上是一串字符串,比较小巧,一般存放在客户端 ?? ?构成: ?? ??? ?1, 头部(Header) 头部是json形式,一般存放的是加密的方式和jwt的类型, ?? ??? ?2, 载荷(Playload) 载荷是json形式,存放的是一些基本信息, 如过期时间,要发给谁,签发者是谁,签发时间是多少 ?? ??? ?3, 签证(signature) 签证的构成稍有复杂,将头部和载荷使用base64加密过后,同过.进行连接,并且使用header中的加密方式进行secret加盐加密,最后才得出签证的值 ?? ??? ?4, 整个jwt看起来像是这样: eyJhbGciOiJI.eyJzdWIiOydWV9.TJVA95OrM7E2cB ?? ??? ? ?? ?流程: ?? ??? ?当浏览器向服务器发送请求后,服务器在响应客户端的同时,会在服务器内部把用户的一些不敏感信息放入在jwt的载荷中,如id, name等,生成jwt,并将jwt一并响应给客户端,客户端接收到这个jwt之后,会存放在本地, ?? ??? ?以后每一次请求都会携带这个jwt,以便于保存用户的登录状态,如果用户需要登出,则把客户端的jwt删除即可, ?? ??? ?由于头部和载荷都是采用base64进行的加密,理所应当也可以进行解密,因此头部和载荷是不安全的,而由于签证是由加盐算法进行加密的,因此不能被篡改, 而一旦有人篡改了头部或者载荷,在服务器收到请求之后, ?? ??? ?服务器会把收到的载荷和头部采用相同的secret进行加盐加密,得到新的签证,如果跟老的签证不一致,则说明信息被篡改了,直接返回浏览器错误信息即可. ?? ??? ? 总结: ?? ??? ?session和cookie相比,其实是拿存储空间换取数据安全 ?? ??? ?jwt和session,cookie相比,是以计算力(频繁的加解密)换取存储空间 ?? ????
?
|