此文章旨在帮助大家了解WEB会话
Web会话管理概述
会话是什么
在人机交互时,会话管理是保持用户的整个会话活动的互动与计算机系统跟踪过程。 会话管理分类:桌面会话管理、浏览器会话管理、Web服务器的会话管理。
可以借助通话来理解:小明给小红打电话,拨号过程是会话建立过程,通话过程就是会话保持阶段,双方说话就是传输数据,挂断电话就是会话断开。其实这个过程还有很多细节,比如小明给小红拨号,肯定要提前知道小红地址,也就是手机号;小红如何知道是谁打来的,因为她可以决定接不接,这就属于身份识别问题等等。接下来我们重点是去了解Web会话。
WEB为什么需要会话管理
这里我们应该先对HTTP协议有所了解,详细内容可以看我之前这篇文章:
https://blog.csdn.net/weixin_42081313/article/details/124747385
HTTP是本身一种无状态协议,一次请求结束,客户端与服务端的连接就会断开,服务器再次收到请求时,无法识别此次请求是哪个用户发过来的,需要重新建立连接。也就是说我们在每次登录完网站关闭页面,下次打开又要重新登录,因为HTTP协议没有“记忆”。
但是我们平时在用浏览器访问网页的时候,好像并没有这样。我们感受到的是这种情况:打开一个网站,认证通过登录后在关闭网页,甚至是关闭浏览器再次打开我们依旧是已登录的状态。当我们主动退出自己的账号,或者是清空浏览器的缓存,那么再次登录就需要再次进行身份认证了。其实这里就是就是通过一些辅助技术让服务器“记住”我们,或者我们再次访问网页的时候自动带着我们的身份信息。
为了判断发送请求的用户,需要一种记录用户的方式,也就是Web应用会话管理。
Web应用会话管理的方式
常见的Web应用会话管理的方式有这么几种:
基于server端session的管理方式 ;
基于cookie的管理方式;
基于token的管理方式。
这几种应用的场景是不同的,也各有有缺点。
基于server端session的管理的方式
session会话管理原理
在早期的Web应用中,通常使用服务端session来管理用户的会话。
服务端session是用户第一次访问应用时,服务器就会创建的对象,代表用户的一次会话过程,可以用来存放数据。服务器为每一个session都分配一个唯一的session ID, 以保证每个用户都有一个不同的session对象。
服务器在创建完session后,会把session ID通过cookie返回给用户所在的浏览器, 这样当用户第二次及以后向服务器发送请求的时候,就会通过cookie把session ID传回给服务器,以便服务器能够根据session ID找到与该用户对应的session对象。
session通常设定有有效时间,比如1个小时。当时间失效后,服务器会销毁之前的 session,并创建新的session返回给用户。但是只要用户在失效时间内,有发送新的请求给服务器,通常服务器都会把他对应的session的有效时间根据当前的请求时间再重新刷新。
session在一开始并不具备会话管理的作用。它只有在用户登录认证成功之后,并且往session对象里面放入了用户登录成功的凭证,才能用来管理会话。管理会话的逻辑也很简单,只要拿到用户的session对象,看它里面有没有登录成功的凭证,就能判断这个用户是否已经登录。当用户主动退出的时候,会把它的session对象里的登录凭证清掉。所以在用户登录前或退出后或者session对象失效时,肯定都是拿不到需要的登录凭证的。
session实现会话管理的流程:
session会话管理优缺点
优点:
1、某些地方使用可以简化Web开发:如果在诸多Web页面间传递一个变量,那么用session变量要比通过QueryString传递变量可使问题简化。
2、安全性好:客户端与服务端保持会话状态的媒介始终只是一个session ID串,只要这个串够随机,攻击者就不能轻易冒充他人的session ID进行操作;除非通过CSRF或 http劫持的方式,才有可能冒充别人进行操作;即使冒充成功,也必须被冒充的用户 session里面包含有效的登录凭证才行。
缺点:
1、这种方式将会话信息存储在Web服务器里面,当用户同时在线量比较多时,这些会话信息会占据比较多的内存;
2、当应用采用集群部署的时候,会遇到多台web服务器之间如何做session共享的问题。
3、多个应用要共享session时,还会遇到跨域问题。不同的应用可能部署的主机不 一样,需要在各个应用做好cookie跨域的处理。
session会话管理实现代码逻辑
基于cookie的管理方式
Cookie和session区别
session的管理方式会增加服务器的负担和架构的复杂性,所以后来就提出把用户的登录凭证直接存到客户端的方案,当用户登录成功之后,把登录凭证写到cookie里面, 并给cookie设置有效期,后续请求直接验证存有登录凭证的cookie是否存在以及凭证是否有效,即可判断用户的登录状态。
Cookie是客户端保存用户信息的一种机制,用来记录用户的一些信息,存储在客户端的文件中。
Session将数据存储在服务端。
Cookie和Session应用场景
Cookie应用场景:
比如我们在登录一个购物网站后,可以看到自己的订单信息,如果网页关闭,想再次查看自己的订单信息,并不用再次输入自己的用户名密码,而是已经是登录状态了直接可以查看。这是因为客户端已经将用户登录后的Cookie存入到客户端文件中,此文件并不会因为浏览器关闭而消失,用户再次访问此网站,浏览器会自动查找存储的 Cookie文件是否有此网站的登录信息,如果有此网站的登录信息,就不需要再次验证身份信息可直接访问,如果设置了Cookie时间会在相应的时间到期后自动删除,这时就需要输入身份验证信息再次验证。
Session应用场景:
比如我们在登录一个购物网站后,选择了很多商品加入到购物车之后,服务器端是如何判断哪些商品是哪个用户选择的,就是通过Session来进行判断的。客户端在第一次访问服务器后,服务器会创建一个Session信息,然后客户端再请求服务器,都会带着这个Session信息,这样服务器区分不同的客户端请求。
基于cookie的管理方式原理
用户发起登录请求,服务端根据传入的用户密码之类的身份信息,验证用户是否满足登录条件,如果满足,就根据用户信息创建一个登录凭证,这个登录凭证简单来说就是一个对象,最简单的形式可以只包含用户id、凭证创建时间和过期时间三个值。
服务端把上一步创建好的登录凭证,先对它做数字签名,然后再用对称加密算法做加密处理,将签名、加密后的字串,写入cookie。cookie的名字必须固定(如 ticket),因为后面再获取的时候,还得根据这个名字来获取cookie值。这一步添加数字签名的目的是防止登录凭证里的信息被篡改,因为一旦信息被篡改,那么下一步做签名验证的时候肯定会失败。做加密的目的,是防止cookie被别人截取的时候,无法轻易读到其中的用户信息。
用户登录后发起后续请求,服务端根据上一步存登录凭证的cookie名字,获取到相关的cookie值。然后先做解密处理,再做数字签名的认证,如果这两步都失败,说明这个登录凭证非法;如果这两步成功,接着就可以拿到原始存入的登录凭证了。然后用这个凭证的过期时间和当前时间做对比,判断凭证是否过期,如果过期,就需要用户再重新登录;如果未过期,则允许请求继续。
Cookie实现会话管理流程
Cookie会话管理优缺点
优点:
1、实现了服务端的无状态化(最大的优点),服务端只需要负责创建和验证登录cookie即可,无需保持用户的状态信息。
2、cookie可以跨越同域名下的的多个网页,但不能跨越多个域名使用
3、可以设置有效期限,控制cookie的生命周期,使之不会永远有效(攻击者可能拿到的是过期的cookie)
缺点:
1、cookie有大小限制,存储不了太多数据。
2、每次传送cookie,增加了请求的数量,对访问性能也有影响。
3、同样存在跨域问题(不同域名无法互相读取cookie)
基于token的管理方式
Session和Cookie两种会话管理方式由于都要用到Cookie,不适合用在native app里面,因为native app不是浏览器,不好管理Cookie,因此都不适合做纯API服务的登录认证。要实现API服务的登录认证,就需要用到token-based的会话管理方式。
token-based的管理方式从流程上和实现上跟cookie-based的管理方式没有太多区别,只不过cookie-based的管理方式中写到cookie里面的ticket在这种方式下称为 token,这个token在返回给客户端之后,后续请求都必须通过url参数或者是http header的形式,主动带上token,这样服务端接收到请求之后就能直接从http header 或者url里面取到token进行验证。
token实现会话管理流程
token-based的管理方式优缺点
优点:
1、支持跨域访问:Cookie是不支持跨域访问的,Token支持
2、无状态:Token无状态,Session有状态(有状态和无状态最大的区别就是服务端会不会保存客户端的信息)3、支持移动设备:Token更适用于移动应用,Cookie不支持手机端访问。
缺点:
1、占带宽:正常情况下Token要比session ID更大,需要消耗更多的流量,挤占更多带宽
2、无法在服务端注销,很难解决劫持问题