web server 与 browser 的会话保持

        我们知道HTTP协议是无状态的,用户每次请求web页面,都与服务器之间建立了单独的连接,服务器并不知道两次请求之间的上下文关系,因此一次登录之后,下次请求,要希望服务器知道你已经登录过了,你是谁,保持住你与服务器之间的会话,就必须采取借助特殊的手段来实现,本文以tomcat为例介绍。

       目前有两种机制来解决这个问题:

       1)cookie

       关于cookie的介绍可以参考 婉转PHP 的这篇博客,写的很好。

       http://www.cnblogs.com/wansiphp/articles/1950633.html

       session在服务器端保存用户状态信息,例如用户登录之后会在服务器端session中记住一些信息,但是这些单纯的session是不够的,打个比方,服务器是银行,某次你去银行存了一笔钱,银行在账单(session)里面记了一笔,下次你说你要去取,柜台的MM并不认识你,不知道账单里面哪一笔钱是你的,有没有存过钱,所以存钱后银行的柜台MM会给你一个存折(cookie),存折里面有你的存单编号(jsessionid),你把存折放在家里(浏览器),你下次拿着存折去银行,柜台MM根据你的存单编(jsessionid)去查帐(session)就OK了。

       cookie和session一起配合,实现了状态的保持。



      第一次访问服务器,request请求头中并不会携带有cookie信息,server端发现来了一个陌生人,于是建立了一个会话session,产生了新的jsessionid,并把它写到response响应头中,浏览器根据response header的信息,去把这个信息写到内存中,注意这个cookie不会持久化存储到文件中,浏览器关闭后会话将丢失。



    下次再去访问服务器,便会携带这个jsessionid信息,服务器便知道来着身份,不再给你Set-Cookie了。



      但是,不幸的是,cookie太过开放了,常被用来记录用户访问行为,涉及到个人隐私,用户可以在浏览器中设置禁用cookie,cookie禁了,方案1就彻底歇菜了...因此,你懂的,就有了方案2。

     2)url重写

     为了在cookie被禁用的情况下,依然可以保持会话,tomcat支持这种URL重写的机制,显式地把jsessionid放在URL中传输,例如

   http://www.sample.com/index.htm;jsessionid=43rdf3fr45y

    我们来看看tomcat内部是如何处理的吧

    请见tomcat源代码中CoyoteAdapter类中的postParseRequest方法,首先会调用parseSessionId方法去URI中拿jsessionid

    

    然后再调用parseSessionCookiesId方法去cookie中取



    这里提到了会覆盖URI中取到的值,并且如果cookie中有多个jsessionid,只要第一个。

    笔者验证了这一过程,在都有的情况下,cookie覆盖了URI中的jsessionid,以cookie中为准。    

    这里会有一个问题,如果服务器response写了set-cookie,但是浏览器禁用了cookie,下次请求没有携带cookie来,服务器会自动得重写URL吗?

    答案是NO,如果浏览器禁了cookie,tomcat是不知道浏览器端情况的,只能不停的刷出一个个新的jsessionid

    需要开发人员在程序中根据情况选择是否要重写URL了,可以使用response.encodeURL()实现重写。

    我们来看看tomcat源码中这个方法的内部实现把。


    tomcat的做法很聪明,进行了一步判断,如果cookie中含有jsessionid信息,那么你让我在URL中追加jsessionid我也不干。

    至此,两个方案都介绍完毕了。

    url中携带jsessionid会有安全方面的隐患,如果你正在登录一个网站,然后这个带jsessionid的URL泄漏出去了,那么别人打开这个链接,就拥有了你的身份,对于那些server端session保持时间特别长的应用,尤其危险。


   

      

      










评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值