深入理解Web会话管理的方式
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
深入理解Web会话管理的方式
http是无状态的,一次请求结束,连接断开,下次服务器再收到请求,它就不知道这个请求是哪个用户发过来的。当然它知道是哪个客户端地址发过来的,但是对于我们的应用来说,我们是靠用户来管理,而不是靠客户端。所以对我们的应用而言,它是需要有状态管理的,以便服务端能够准确的知道http请求是哪个用户发起的,从而判断他是否有权限继续这个请求。这个过程就是常说的会话管理。它也可以简单理解为一个用户从登录到退出应用的一段期间。本文总结了3种常见的实现web应用会话管理的方式:
1)基于server端session的管理方式
2)cookie-base的管理方式
3)token-base的管理方式
这些内容可以帮助加深对web中用户登录机制的理解,对实际项目开发也有参考价值,欢迎阅读与指正。
1. 基于server端session的管理
在早期web应用中,通常使用服务端session来管理用户的会话。快速了解服务端session:
1) 服务端session是用户第一次访问应用时,服务器就会创建的对象,代表用
户的一次会话过程,可以用来存放数据。服务器为每一个session都分配一个唯一的sessionid,以保证每个用户都有一个不同的session对象。
2)服务器在创建完session后,会把sessionid通过cookie返回给用户所在的浏览器,这样当用户第二次及以后向服务器发送请求的时候,就会通过cookie 把sessionid传回给服务器,以便服务器能够根据sessionid找到与该用户对应的session对象。
3)session通常有失效时间的设定,比如2个小时。当失效时间到,服务器会销毁之前的session,并创建新的session返回给用户。但是只要用户在失效时间内,有发送新的请求给服务器,通常服务器都会把他对应的session的失效时间根据当前的请求时间再延长2个小时。
4)session在一开始并不具备会话管理的作用。它只有在用户登录认证成功之后,并且往sesssion对象里面放入了用户登录成功的凭证,才能用来管理会话。管理会话的逻辑也很简单,只要拿到用户的session对象,看它里面有没有登录成功的凭证,就能判断这个用户是否已经登录。当用户主动退出的时候,会把它的session对象里的登录凭证清掉。所以在用户登录前或退出后或者session对象失效时,肯定都是拿不到需要的登录凭证的。
以上过程可简单使用流程图描述如下:
主流的web开发平台(java,.net,php)都原生支持这种会话管理的方式,而且开发起来很简单,相信大部分后端开发人员在入门的时候都了解并使用过它。它还有一个比较大的优点就是安全性好,因为在浏览器端与服务器端保持会话状态的媒介始终只是一个sessionid串,只要这个串够随机,攻击者就不能轻易冒充他人的sessionid进行操作;除非通过CSRF或http劫持的方式,才有可能冒充别人进行操作;即使冒充成功,也必须被冒充的用户session里面包含有效的登录凭证才行。但是在真正决定用它管理会话之前,也得根据自己的应用情况考虑以下几个问题:
1)这种方式将会话信息存储在web服务器里面,所以在用户同时在线量比较多时,这些会话信息会占据比较多的内存;
2)当应用采用集群部署的时候,会遇到多台web服务器之间如何做session 共享的问题。因为session是由单个服务器创建的,但是处理用户请求的服务器不一定是那个创建session的服务器,这样他就拿不到之前已经放入到session 中的登录凭证之类的信息了;
3)多个应用要共享session时,除了以上问题,还会遇到跨域问题,因为不同的应用可能部署的主机不一样,需要在各个应用做好cookie跨域的处理。
针对问题1和问题2,我见过的解决方案是采用redis这种中间服务器来管理session的增删改查,一来减轻web服务器的负担,二来解决不同web服务器共享session的问题。针对问题3,由于服务端的session依赖cookie来传递sessionid,所以在实际项目中,只要解决各个项目里面如何实现sessionid的cookie跨域访问即可,这个是可以实现的,就是比较麻烦,前后端有可能都要做处理。
如果不考虑以上三个问题,这种管理方式比较值得使用,尤其是一些小型的web 应用。但是一旦应用将来有扩展的必要,那就得谨慎对待前面的三个问题。如果真要在项目中使用这种方式,推荐结合单点登录框架如CAS一起用,这样会使应用的扩展性更强。
2. cookie-based的管理方式
由于前一种方式会增加服务器的负担和架构的复杂性,所以后来就有人想出直接把用户的登录凭证直接存到客户端的方案,当用户登录成功之后,把登录凭证写到cookie里面,并给cookie设置有效期,后续请求直接验证存有登录凭证的cookie是否存在以及凭证是否有效,即可判断用户的登录状态。使用它来实现会话管理的整体流程如下:
1)用户发起登录请求,服务端根据传入的用户密码之类的身份信息,验证用户是否满足登录条件,如果满足,就根据用户信息创建一个登录凭证,这个登录凭证简单来说就是一个对象,最简单的形式可以只包含用户id,凭证创建时间和过期时间三个值。
2)服务端把上一步创建好的登录凭证,先对它做数字签名,然后再用对称加密算法做加密处理,将签名、加密后的字串,写入cookie。cookie的名字必须固定(如ticket),因为后面再获取的时候,还得根据这个名字来获取cookie值。这一步添加数字签名的目的是防止登录凭证里的信息被篡改,因为一旦信息被篡改,那么下一步做签名验证的时候肯定会失败。做加密的目的,是防止cookie 被别人截取的时候,无法轻易读到其中的用户信息。
3)用户登录后发起后续请求,服务端根据上一步存登录凭证的cookie名字,获取到相关的cookie值。然后先做解密处理,再做数字签名的认证,如果这两步都失败,说明这个登录凭证非法;如果这两步成功,接着就可以拿到原始存入的登录凭证了。然后用这个凭证的过期时间和当前时间做对比,判断凭证是否过