深入理解Session与Cookie

深入理解Session与Cookie 2014-09-03 09:45:11

分类: Web开发

        Session与Cookie的作用都是为了保持访问用户与后端服务器的交互状态。它们有各自的有点,也有各自的缺陷,然而具有讽刺意味的是它们的优点和它们的使用场景又是矛盾的。例如:使用Cookie来传递信息时,随着Cookie个数的增多和访问量的增加,它占用的网络带宽也很大,试想假如Cookie占用200个字节,如果一天的PV有几亿,那么它要占用多少带宽?所以有大访问量时希望用Session,但是Session的致命弱点是不容易在多台服务器之间共享,这也限制了Session的使用。
一、理解Cookie
        Cookie的作用通俗地说就是当一个用户通过HTTP访问一个服务器时,这个服务器会将一些Key/Value键值对返回给客户端浏览器,并给这些数据加上一些限制条件,在条件符合时这个用户下次访问这个服务器时,数据又被完整地带回给服务器。
1、Cookie属性项
        当前Cookie有两个版本:Version 0和Version 1,它们有两种设置响应头的表示,分别是“Set-Cookie”和“Set-Cookie2”,这两版本的属性项有些不同,具体如下:
        
        
        我们常用的是Set-Cookie: userName="scq";Version="1";Domain="taobao.com";Max-Age=1000。
2、Cookie如何工作
        我们可以用如下方式在服务端创建Cookie:
        String getCookie(Cookie[] cookies, String key) {
            if (cookies != null) {
                for (Cookie cookie : cookies) {
                    if (cookie.getName().equals(key)) {
                        return cookie.getValue();
                    }
                }
            }
            return null;
        }

        public void doGet(HttpServletRequest request,
                    HttpServletResponse response) 
                    throws IOException, ServletException {
            Cookie[] cookies = request.getCookies();
            String userName = getCookie(cookies, "userName");
            String userAge = getCookie(cookies, "userAge");
            if (userName == null) {
                response.addCookie(new Cookie("userName", "scq"));
            }
            if (userAge == null) {
                response.addCookie(new Cookie("userAge", "28"));
            }
            response.getHeaders("Set-Cookie");
        }
        当我们请求某个URL时,浏览器会根据这个URL路径将符合条件的Cookie放在Request请求头中传回给服务端,服务端通过request.getCookies()来取得所有Cookie。
3、使用cookie的限制
        Cookie是HTTP头中的一个字段,虽然HTTP本身对这个字段并没有多少限制,但是Cookie最终还是存储在浏览器里,所以不同的浏览器对Cookie的存储都有一些限制,下表是一些通常的浏览器对Cookie的大小和数量的限制:
        
4、Cookie小技巧
        查看某个网站颁发的Cookie很简单:在浏览器地址栏中输入javascript:alert (document. cookie),回车,JavaScript脚本会弹出一个对话框显示本网站颁发的所有Cookie的内容。
        Cookie具有不可跨域名性,这一点由浏览器来保证,从而保证用户的隐私安全。浏览器判断一个网站是否能操作另一个网站Cookie的依据是域名。Google与Baidu的域名不一样,因此Google不能操作Baidu的Cookie。需要注意的是,虽然网站images.google.com与网站www.google.com同属于Google,但是域名不一样,原则上二者同样不能互相操作彼此的Cookie。
        附注:用户登录网站www.google.com之后会发现访问images.google.com时登录信息仍然有效,而普通的Cookie是做不到的。这是因为Google做了特殊处理。
        关于Cookie的一篇不错的文章,查看请点击 这里

二、理解Session
        Cookie可以让服务端程序跟踪每个客户端的访问,但是每次客户端的访问都必须传回这些Cookie,如果Cookie很多,则无形地增加了客户端与服务端的数据传输量,而Session的出现正是为了解决这个问题。
        同一个客户端每次和服务端交互时,不需要每次传回所有的Cookie值,而是只要传回一个ID,这个ID是客户端第一次访问服务器时生成的,而且每个客户端是唯一的。这样每个客户端就有了一个唯一的ID,客户端只要传回这个ID就行了,这个ID通常是NAME为JSESSIONID的一个Cookie。
1、Session与Cookie
        下面会介绍Session是如何基于Cookie来工作的,实际上有以下三种方式可以让Session正常工作:
        (1)基于URL Path Parameter,默认支持。
        (2)基于Cookie,如果没有修改Context容器的Cookie标识,则默认也是支持的。
        (3)基于SSL,默认不支持,只有connector.getAttribute("SSLEnabled")为TRUE时才支持。
2、Session如何工作
        有了SessionID,服务端就可以创建HttpSession对象了,第一次触发通过request.getSession()方法。如果当前的SessionID还没有对应的HttpSession对象,那么就创建一个新的,并将这个对象加到org.apache.catalina.Manager的sessions容器中保存。Manager类将管理所有Session的生命周期,Session过期将被回收,服务器关闭,Session将被序列化到磁盘等。只要这个HttpSession对象存在,用户就可以根据SessionID来获取这个对象,也就做到了对状态的保持。

三、Cookie安全问题
        虽然Cookie和Session都可以跟踪客户端的访问记录,但是它们的工作方式显然是不同的,Cookie通过把所有要保存的数据通过HTTP的头部从客户端传递到服务端,又从服务端再传回到客户端,所有的数据都存储在客户端的浏览器里,所有这些Cookie数据可以被访问到,所以Cookie的安全性受到了很大的挑战。
        相比较而言Session的安全性要高很多,因为Session是将数据保存在服务端,只是通过Cookie传递一个SessionID而已,所以Session更适合存储用户隐私和重要的数据。

四、分布式Session框架
1、存在哪些问题
        (1)客户端Cookie存储限制。
        (2)Cookie管理混乱。
        (3)安全令人担忧。
2、可以解决哪些问题
        分布式Session框架可以解决的问题:
        (1)Session配置的统一管理。
        (2)Cookie使用的监控和统一规范管理。
        (3)Session存储的多元化。
        (4)Session配置的动态修改。
        (5)Session加密key的定期修改。
        (6)充分的容灾机制,保持框架的使用稳定性。
        (7)Session各种存储的监控和报警支持。
        (8)Session框架的可扩展性,兼容更多的Session机制。
        (9)跨域名Session与Cookie如何让共享的问题。
3、总体实现思路
        为了实现上面的目标,我们需要一个服务订阅服务器,在应用启动时可以从这个订阅服务器订阅这个应用需要的可写Session项和可写Cookie项,这些配置的Session和Cookie可以限制这个应用能够使用哪些Session和Cookie,甚至可以控制Session和Cookie可读或者可写。这样可以精确地控制哪些应用可以操作哪些Session和Cookie,可以有效控制Session的安全性和Cookie的数量,具体如下图所示:
        
        关于这个订阅服务器现在有很多开源的配置服务器,如Zookeeper集群管理服务器,可以统一管理所有服务器的配置文件。
        
五、Cookie压缩
        如果Cookie的量非常大,可以将Cookie的多个k/v对看成普通文本,做文本压缩,压缩算法可以使用gzip和deflate算法。
        需要注意的是,根据Cookie的规范,在Cookie中不能包含控制字符,仅能包含ASCII码为34~126的可见字符,所以要将压缩后的结果再进行转码,可以进行Base32或者Base64编码。

六、表单重复提交问题
        在网站中有很多地方都存在表单重复提交的问题,如用户在网速慢的情况下可能会重复提交表单,又如恶意用户通过程序来发送恶意请求等,这时都需要设计一个防止表单重复提交的机制。
        要防止表单重复提交,就要标识用户的每一次访问请求,使得每一次访问对服务端来说都是唯一确定的。为了标识用户的每次访问请求,可以在用户请求一个表单页面时,为表单域增加一个隐藏表单项,这个表单项的值每次都是一个唯一的token,这个token可以是服务端生成的一个随机数,服务端在收到用户请求页面时生成这个token后保存在用户的Session中,等用户提交表单请求时检查这个token和当前Session中保存的token是否一致,如果一致说明没有重复提交,否则说明非法请求。隐藏表单项可以如下来实现:
        

        
        


七、多终端Session统一
        多终端Session统一的方案主要有如下两个:
1、多端共享Session
        
        后端服务统一的数据结构和存储。
2、多终端登录
        
        扫描登陆。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值