Chinaunix首页 | 论坛 | 博客
  • 博客访问: 331383
  • 博文数量: 106
  • 博客积分: 1115
  • 博客等级: 少尉
  • 技术积分: 806
  • 用 户 组: 普通用户
  • 注册时间: 2006-08-04 08:06
文章分类

全部博文(106)

文章存档

2015年(4)

2014年(48)

2013年(15)

2012年(38)

2011年(1)

我的朋友

分类: Web开发

2014-09-04 23:53:29

http://blog.chinaunix.net/uid-22312037-id-4451820.html
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的大小和数量的限制:
        

二、理解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、多终端登录
        
        扫描登陆。

阅读(530) | 评论(0) | 转发(0) |
0

上一篇: gdb调试core文件

下一篇:十分钟学会Python

给主人留下些什么吧!~~