◼️ 什么是会话
会话: 数据交互的过程,在web中指 浏览器从发出一个请求到浏览器关闭,这个过程就是一个会话。在这个过程中,需要有很多的状态和数据需要我们关注,记录,这个就是我们要研究的会话
◼️ 什么是会话机制
http协议是短连接无状态的,所以需要cookie和session进行保存用户身份验证,从根本上解决了用户持续访问的问题。
cookie是服务器下发保存在本地的,因此cookie不安全,容易被篡改。
session是临时的,关闭浏览器自动删除。
会话技术详细过程
在浏览器中输入域名url,会经过dns服务器将域名解析成ip返回后,浏览器发送request对象请求给服务器,服务器收到请求后创建一个session对象,该对象会有个session_key的值,服务器会将该值以set_cookie消息头的形式发送给浏览器,浏览器接收到后,会将session_key的变量定义为session_id,session_id会存储在cookie中,当浏览器再次访问时,就会携带着session_id去服务器找对应的数据
◼️ 什么是cookie
Cookie是一种客户端会话技术,所有数据存储在客户端,其是以key-value进行数据存储层,服务器中是不做任何存储。
cookie 是一个非常具体的东西,指的就是浏览器里面能永久存储的一种数据,仅仅是浏览器实现的一种数据存储功能。
cookie由服务器生成,发送给浏览器,浏览器把cookie以key,value
形式保存到某个目录下的文本文件内,下一次请求同一网站时会把该cookie发送给服务器。
由于cookie是存在客户端上的,所以浏览器加入了一些限制确保cookie不会被恶意使用,同时不会占据太多磁盘空间,所以每个域的cookie数量是有限的。
♦️ 总结:cookie是一段小型文本数据。
Cookie是一段不超过4KB的小型文本数据,保存在客户端浏览器中,由一个名称(Name)、一个值(Value)和其它几个用于控制Cookie有效期、安全性、使用范围的可选属性组成。其中 :
(1) Name/Value:设置Cookie的名称及相对应的值,对于认证Cookie,Value值包括Web服务器所提供的访问令牌。
(2) Expires属性:设置Cookie的生存期。有两种存储类型的Cookie:会话性与持久性。Expires属性缺省时,为会话性Cookie,仅保存在客户端内存中,并在用户关闭浏览器时失效;持久性Cookie会保存在用户的硬盘中,直至生存期到或用户直接在网页中单击“注销”等按钮结束会话时才会失效 。
(3) Path属性:定义了Web站点上可以访问该Cookie的目录 。
(4) Domain属性:指定了可以访问该 Cookie 的 Web 站点或域。
◼️ 什么是session
session是一种服务端会话技术,其把所有数据存储在服务器中,默认存在服务器的内存中,其的存储结构也是key-value形式。
session 从字面上讲,就是会话。这个就类似于你和一个人交谈,你怎么知道当前和你交谈的是张三而不是李四呢?这个时候就是session在起作用,session好比就是张三身上的某个特征来表明他就是张三。
session用在服务器与浏览器对话中,也是类似的道理,服务器要知道当前发请求给自己的是谁。为了做这种区分,服务器就要给每个客户端分配不同的“身份标识”,然后客户端每次向服务器发请求的时候,都带上这个“身份标识”,服务器就知道这个请求来自于谁了。
至于客户端怎么保存这个“身份标识”,可以有很多种方式,对于浏览器客户端,大家都默认采用 cookie 的方式。
服务器使用session把用户的信息临时保存在了服务器上,用户离开网站后session会被销毁,也就是说session用完即弃。所以说,session这种用户信息存储方式相对cookie来说更安全些,可是session有一个缺陷:如果web服务器做了负载均衡,那么下一个操作请求到了另一台服务器的时候session会丢失。
◼️ cookie和session小结
1、cookie: 客户端浏览器的缓存;session: 服务端服务器的缓存。
2、cookie不是很安全,别人可以分析存放在本地的cookie并进行cookie欺骗,考虑到安全应当使用session。
3、session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能,考虑到减轻服务器性能方面,应当使用cookie。
4、可以考虑将登陆信息等重要信息存放为session,其他信息如果需要保留,可以放在cookie中。
session与cookie功能效果相同。Session与Cookie的区别在于Session是记录在服务端的,而Cookie是记录在客户端的。
当访问服务器否个网页的时候,会在服务器端的内存里开辟一块内存,这块内存就叫做session,而这个内存是跟浏览器关联在一起的。这个浏览器指的是浏览器窗口,或者是浏览器的子窗口,意思就是,只允许当前这个session对应的浏览器访问,就算是在同一个机器上新启的浏览器也是无法访问的。而另外一个浏览器也需要记录session的话,就会再启一个属于自己的session。
◼️ 什么是token
1、Token的出现(引入):Token是在客户端大量的向服务器端请求数据,服务器端频繁的拿着用户名密码去数据库里面执行查询操作并进行对比,判断用户名和密码正确与否,并作出相应提示,在这样的背景下,Token便应运而生。
2、Token的定义(应用):Token在服务器端生成一个字符串,作为客户端请求数据的令牌,当用户第一次登录后,服务器就会生成一个Token字符串,并且将此Token返回给客户端,以后客户端只需带上这个Token前来请求数据即可,无需再次带上用户名和密码。
3、token的简单形式:uid(用户唯一的身份标识)、time(当前时间的时间戳)、sign(签名,主要是由token的前几位+哈希算法经过压缩,组合成字符串,防止恶意的三方拼接盗取token)
4、使用Token的目的:Token的目的是为了减轻服务器的压力,减少频繁的查询数据库,使服务器更加健壮。
◼️ 如何使用token?
1、用设备号/设备mac地址作为Token(推荐)
客户端:客户端在登录的时候获取设备的设备号/mac地址,并将其作为参数传递到服务端。
服务端:服务端接收到该参数后,便用一个变量来接收同时将其作为Token保存在数据库,并将该Token设置到session中,客户端每次请求的时候都要统一拦截,并将客户端传递的token和服务器端session中的token进行对比,如果相同则放行,不同则拒绝。
分析:此刻客户端和服务器端就统一了一个唯一的标识Token,而且保证了每一个设备拥有了一个唯一的会话。该方法的缺点是客户端需要带设备号/mac地址作为参数传递,而且服务器端还需要保存;优点是客户端不需重新登录,只要登录一次以后一直可以使用,至于超时的问题是有服务器这边来处理,如何处理?若服务器的Token超时后,服务器只需将客户端传递的Token向数据库中查询,同时并赋值给变量Token,如此,Token的超时又重新计时。
2、用session值作为Token
客户端:客户端只需携带用户名和密码登陆即可。
服务端:服务端接收到用户名和密码后并判断,如果正确了就将本地获取sessionID作为Token返回给客户端,客户端以后只需带上请求数据即可。
分析:这种方式使用的好处是方便,不用存储数据,但是缺点就是当session过期后,客户端必须重新登录才能进行访问数据。
◼️ token的优势
无状态、可扩展
在客户端存储的Tokens是无状态的,并且能够被扩展。基于这种无状态和不存储Session信息,负载负载均衡器能够将用户信息从一个服务传到其他服务器上。
如果我们将已验证的用户的信息保存在Session中,则每次请求都需要用户向已验证的服务器发送验证信息(称为Session亲和性)。用户量大时,可能会造成一些拥堵。
但是不要着急。使用tokens之后这些问题都迎刃而解,因为tokens自己hold住了用户的验证信息。
安全性
请求中发送token而不再是发送cookie能够防止CSRF(跨站请求伪造)。即使在客户端使用cookie存储token,cookie也仅仅是一个存储机制而不是用于认证。不将信息存储在Session中,让我们少了对session操作。
token是有时效的,一段时间之后用户需要重新验证。我们也不一定需要等到token自动失效,token有撤回的操作,通过token revocataion可以使一个特定的token或是一组有相同认证的token无效。
可扩展性
Tokens能够创建与其它程序共享权限的程序。例如,能将一个随便的社交帐号和自己的大号(Fackbook或是Twitter)联系起来。当通过服务登录Twitter(我们将这个过程Buffer)时,我们可以将这些Buffer附到Twitter的数据流上(we are allowing Buffer to post to our Twitter stream)。
使用tokens时,可以提供可选的权限给第三方应用程序。当用户想让另一个应用程序访问它们的数据,我们可以通过建立自己的API,得出特殊权限的tokens。
多平台跨域
我们提前先来谈论一下CORS(跨域资源共享),对应用程序和服务进行扩展的时候,需要介入各种各样的设备和应用程序。
Having our API just serve data, we can also make the design choice to serve assets from a CDN. This eliminates the issues that CORS brings up after we set a quick header configuration for our application.
只要用户有一个通过了验证的token,数据和资源就能够在任何域上被请求到。
Access-Control-Allow-Origin: *
◼️ 有何区别
这里就讲述一下session与token的区别,这里以一个flask项目举例,session是把flask存在服务器的,服务器存放一个session值,向前端下发一个key,然后前端访问的时候会携带这个key进行访问,再去服务器寻找key对应的值,如果找到了就校验成功,这是一个项目生成与下发session的具体流程。
这时对于这个session校验就会产生一个问题,如果我们这个项目做了负载均衡,后端采用多台服务器放置数据呢?用户每次登陆会被引向不同的服务器,这时候还要校验用户身份是不是就需要每台服务器都存放一个session对应的value呢?
为了解决这个问题,就不再使用session校验,而是使用token,在token技术里,服务器端存放一个加密校验方式,不存放任何用户的session之类的数据,用户访问服务器,在服务器端生成一个加密后的返回一个带签名的token下发给前端,前端页面保存这个token,以后每次访问在请求头heads
中携带这个token进行访问就可以了。服务端会验证token,校验成功则返回请求数据,校验失败则返回错误码。
至此,因为是服务器不存放value值,所以不用一一对应前端的key和后端的value,因此也就解决了跨域访问的问题,也解决了负载均衡下多台服务器的问题。
参考资料:深度剖析cookie、session、token
参考资料:会话技术:cookie、session、token简析
参考资料:什么是token?token是用来干嘛的?
参考资料:傻傻分不清之 Cookie、Session、Token、JWT