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) |