Session和Cookie的作用都是为了保持访问用户与后端服务器的交互状态。他们有各自的优点,也有各自的缺点,然而具有讽刺意味的是他们的优点和他们的使用场景又是矛盾的。例如Cookie来传递信息时,随着Cookie个数的增多和访问量的增加,它占用的网络宽带也很大。所以有大访问量时希望用Session,但是Session的致命弱点是不容易在多台服务器之间共享,这也限制了Session的使用。
1 理解Cookie
Cookie的作用通俗的说就是当一个用户通过Http访问一个服务端时,这个服务器会将一些key/value键值对返回给客户端浏览器,并给这些数据加上一些限制条件,在条件符合时这个用户下次访问这个服务器时,数据又会被完整的带会给服务器。
Web应用程序是使用HTTP协议传输数据的。HTTP协议是无状态的协议。一旦数据交换完毕,客户端与服务器端的连接就会关闭,再次交换数据需要建立新的连接。这就意味着服务器无法从连接上跟踪会话。即用户A购买了一件商品放入购物车内,当再次购买商品时服务器已经无法判断该购买行为是属于用户A的会话还是用户B的会话了。要跟踪该会话,必须引入一种机制。
Cookie实际上是一小段的文本信息。客户端请求服务器,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个Cookie。客户端浏览器会把Cookie保存起来。当浏览器再请求该网站时,浏览器把请求的网址连同该Cookie一同提交给服务器。服务器检查该Cookie,以此来辨认用户状态。服务器还可以根据需要修改Cookie的内容。
2.理解Session
前面已经介绍了 Cookie 可以让服务端程序跟踪每个客户端的访问,但是每次客户端的访问都必须传回这些 Cookie,如果 Cookie 很多,这无形地增加了客户端与服务端的数据传输量,而 Session 的出现正是为了解决这个问题。 同一个客户端每次和服务端交互时,不需要每次都传回所有的 Cookie 值,而是只要传回一个 ID,这个 ID 是客户端第一次访问服务器的时候生成的,而且每个客户端是唯一的。这样每个客户端就有了一个唯一的 ID,客户端只要传回这个 ID 就行了,这个 ID 通常是 NANE 为 JSESIONID 的一个 Cookie。
2.1Session与Cookie
下面详细讲一下 Session 如何基于 Cookie 来工作。实际上有三种方式能可以让 Session 正常工作:
基于 URL Path Parameter,默认支持。
基于 Cookie,如果没有修改 Context 容器的 cookies 标识,默认也是支持的。
基于 SSL,默认不支持,只有 connector.getAttribute(“SSLEnabled”) 为 TRUE 时才支持。
2.2Session如何工作
有了 Session ID 服务端就可以创建 HttpSession 对象了,第一次触发通过 request.getSession() 方法。如果当前的 Session ID 还没有对应的 HttpSession 对象,那么就创建一个新的,并将这个对象加到 org.apache.catalina. Manager 的 sessions 容器中保存。Manager 类将管理所有 Session 的生命周期,Session 过期将被回收,服务器关闭,Session 将被序列化到磁盘等。只要这个 HttpSession 对象存在,用户就可以根据 Session ID 来获取这个对象,也就达到了状态的保持。
3 cookie 和session 的区别:
1、cookie数据存放在客户的浏览器上,session数据放在服务器上.
2、cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗考虑到安全应当使用session。
3、session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能考虑到减轻服务器性能方面,应当使用COOKIE。
4、单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。(Session对象没有对存储的数据量的限制,其中可以保存更为复杂的数据类型)
注意:
session很容易失效,用户体验很差;
虽然cookie不安全,但是可以加密 ;
cookie也分为永久 和暂时 存在的;
浏览器 有禁止cookie功能 ,但一般用户都不会设置;
一定要设置失效时间,要不然浏览器关闭就消失了;
例如:
记住密码功能就是使用永久cookie写在客户端电脑,下次登录时,自动将cookie信息附加发送给服务端。
application是全局性信息,是所有用户共享的信息,如可以记录有多少用户现在登录过本网站,并把该信息展示个所有用户。
两者最大的区别在于生存周期,一个是IE启动到IE关闭.(浏览器页面一关 ,session就消失了)
一个是预先设置的生存周期,或永久的保存于本地的文件。(cookie)
4 表单重复提交问题
网站中在很多地方都有表单重复提交问题,一种情况是用户在网速慢的情况下可能会重复提交表单,还有就是恶意用户通过程序来发送恶意请求,在这些情况下都要设计一个防止表单重复提交的机制。
要能够防止表单重复提交,就要标识用户的每一次访问请求,使得每一次访问对服务端来说都是唯一确定的。为了标识用户的每次访问请求,可以在用户请求一个表单域时增加一个隐藏表单项,这个表单项的值每次都是唯一的 token,如:
<form id=”form” method=”post”>
<input type=hidden name=“crsf_token” value=“xxxx”/>
</form>
当用户在请求时生成这个唯一的 token 时,同时将这个 token 保存在用户的 Session 中,等用户提交请求时检查这个 token 和当前的 Session 中保存的 token 是否一致。如果一致,说明没有重复提交,否则用户提交上来的 token 已经不是当前的这个请求的合法 token。其工作过程如图所示。
生成唯一的 token 需要一个算法,最简单的就是可以根据一个种子作为 key 生成一个随机数,并保存在 Session 中,等下次用户提交表单时做验证。验证表单的过程如图所示。