需要很多Cookie时,考虑HTTP对Cookie数量和大小的限制。
几百或更多台服务器的时候,如何解决Session在多态服务器之间共享的问题。
还有一些安全问题,如Cookie被盗,Cookie伪造等。
二者的作用是为了保持访问用户与后端服务器的交互状态。
Cookie个数的增加和访问量的增加,占用的网络带宽也很大;有大量访问量时,希望用session,可是在多态服务器之间如何共享session是个难题。
10.1 理解Cookie
用户通过HTTP访问一个服务器时,服务器将一些KEY/value键值对返回给客户浏览器,并且给这些数据加上一些限制条件,在条件符合时下次互用再访问服务器,数据被完整的带给服务器。
因为HTTP是无状态的,所以可以用cookie存一些个人信息。
10.1.1 Cookie属性项
Cookie[] cookies = request.getCookies();
String userName = getCookie(coolies,'userName')
10.1.2 Cookie如何工作
服务端Cookie是如何加到header?
resonse.addCookie
客户端获取Cookie?
当请求某个URL的时候,浏览器会根据URL路径将符合条件的Cookie放在request请求头中传回给服务器,服务器通过request.getCookies()来取得所有cookies。
10.1.3 使用Cookie的限制
Cookie是HTTP头中的一个字段,Cookie最终还是存储在浏览器,浏览器会规定每个域名存储的Cookie数量和总大小
10.2 理解Session
Cookie可以让服务器程序跟踪每个客户端的访问,但是每次客户端的访问都必须传回这些cookie,如何cookie过多,则加重数据传输量。
session可以解决这个问题:同一客户每次和服务器交互时,不需要每次都传回所有的Cookie值,而是只传一个ID。这个ID是客户端第一次访问服务器时生成的,而且每个客户端是唯一的。这个ID通常是NAME为JSESIONDI的一个cookie.
10.2.1 Session与Cookie
session是如何基于Cookie来工作的。有一下三种方法可以让Session正常工作:
- 基于URL Path Parameter, 默认支持。
当浏览器不支持Cookie时,浏览器将用户的SessionCookieName重写到用户请求的URL中。
web.xml中会配置sessionID的名字,默认是JSESSIONID。根据这个名字可以在URL种拿到sessionID
- 基于Cookie,如果没有修改Context容器的Cookies标识,则默认是支持的。
这个会覆盖第一种。
- 基于SSL,默认不支持,只有connector.getAttribute("SSLEnabled")为true时才支持。
10.2.2 Session如何工作
有了Session ID,服务器就可以创建HttpSession对象了,第一次触发通过request.getSession()方法,如何没有,则创建一个HttpSession.
如果session过期,HttpSession将被回收; 如果服务器关闭,session将被序列化到磁盘。
10.3 Cookie安全问题
因为Cookie存储在浏览器中,可以查看被修改;每次都传递,也不安全;
相对来说,session比较安全,只是保存一个JSESSIONID, 信息都在服务器端。
10.4 分布式session框架
在大型互联网系统中,单独使用Cookie和Session都是不可行的。
10.4.1 存在哪些问题
客户端Cookie存储限制。
安全问题。
占用大量带宽,服务器压力大。
10.4.2 可以解决哪些问题
结合session和Cookie,下面是分布式session框架可以解决的问题。
10.4.3 总体实现思路
一个分布式缓存服务器,session存储到分布式缓存中。
需要一个订阅服务器,应用服务器启动时可以从这个订阅服务器订阅session和Cookie,可以通过配置限制应用服务器对session和Cookie的访问权限,保证了安全。
用订阅服务器集中管理对Cookie的配置,不用每一台配置Cookie;比如一个Cookie项是全局的,就可以统一配置,而不必每台都配置。 Zookeeper集群管理服务器。
应用是集群,不可能将创建的Session都保存在每台应用服务器内存中,要共享session要将他么统一存储在一个分布式缓存中,可以随时写入和读取,性能要好。比如MemCache
上面解决了配置(Zookeeper)和存储(分布式缓存), 如何存取session和Cookie?
既然是分布式session处理框架,必然会重新实现HttpSession的操作接口,使得应用操作session的对象是我们实现的innerHttpSession对象,这个操作要在进入session之前完成,所以可以配置一个filter拦截用户请求。目的是能够调用分布式缓存查询。
可以将一些非常关键的session再存储到Cookie中,分布式缓存出问题了,可以将session存储到Cookie中。
还要一个重要的问题:如何处理跨域名来共享Cookie的问题。Cookie是有域名限制的,也就是在一个域名下的Cookie不能被另一个域名访问。也就是在一个域名登录成功后,如何访问另外一个域名的应用并且保证登录状态仍然有效。
10.5 Cookie压缩
Cookie在HTTP头部,所以通常的gzip和deflate针对HTTP body的压缩不能压缩Cookie。
10.6 表单重复提交问题
网速慢、或者恶意提交会导致重复提交。
在请求表单时生成为一个的token存在session端,同时返回给表单,存再隐藏域。提交的时候,用隐藏域和session中的对比,如果一样就删除掉session中的,并处理业务。
当再次提交的时候,就会失败。 从而可以防止重复提交。
10.7 多终端Session统一
手机的后端和PC的后端的服务系统不是统一的。存在两个问题:
一是:二次登陆的问题;另外一个是:Session能否共享、
解决方案:
(1)多段共享session:分布式session框架,必须要求一致的会员数据结构;写到客户端的Cookie必须一样。
(2)
10.8 总结