状态保持的常用手法,原理,以及优劣

状态保持的常用手法,原理,以及优劣

首先解释问什么要进行状态保持:
    直接原因:
        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相比,是以计算力(频繁的加解密)换取存储空间
       

猜你喜欢

转载自blog.csdn.net/James_Nan/article/details/97684989