session 和 cookie

Cookie的机制

Cookie是浏览器(User Agent)访问一些网站后,这些网站存放在客户端的一组数据,用于使网站等跟踪用户,实现用户自定义功能。

Cookie的Domain和Path属性标识了这个Cookie是哪一个网站发送给浏览器的;Cookie的Expires属性标识了Cookie的有 效时间,当Cookie的有效时间过了之后,这些数据就被自动删除了。

如果不设置过期时间,则表示这个Cookie生命周期为浏览器会话期间,只要关闭浏览器窗口,Cookie就消失了。这种生命期为浏览会话期的 Cookie被称为会话Cookie。会话Cookie一般不保存在硬盘上而是保存在内存里。如果设置了过期时间,浏览器就会把Cookie保存到硬盘 上,关闭后再次打开浏览器,这些Cookie依然有效直到超过设定的过期时间。存储在硬盘上的Cookie可以在不同的浏览器进程间共享,比如两个IE窗 口。而对于保存在内存的Cookie,不同的浏览器有不同的处理方式。

每个Cookie有6个属性,分别 为:Cookies Name; Cookies Value; Domain;Path; Secure; Expire Date。这里给出的Cookie的6个属性和C++中定义的结构体不完全一致。其原因将在Cookie的文件格式小节给出解释。

下面对Cookie结构中的各个属性分别给出解释:
Cookies Name < Key>, 必要属性,指明了Cookie的名字,有一系列字符(不包括括号、逗号、空格等)组成;每个cookie由一个唯一的名称代表,这个名称可以包含字母、数 字、下划线。Cookie的名称是不分大小写,所以mycookie和MyCookie是一样。但考虑到服务器端语言可能区分大小写,所以对程序开发者来 说定义和使用时最好还是区分大小写。
Cookies Value,< Value>Cookie 的值,Web服务器储存在Cookie中的信息;保存在Cookie中的字符串值。这个值在存储之前是用encodeURIComponent()对其进 行编码的,否则会丢失数据或占用了Cookie。而且Cookie名字和值加起来的字节数不能超过4095字节,也即4KB。
Domain, 可选,指明了Cookie的有效域的范围,默认的是产生Cookie的服务器的名字;出于安全考虑,网站不能访问由其他域所创建的Cookie。创建 Cookie以后,域的信息会作为cookie的一部分存储下来。关于域,举个例子来说,如http://www.baidu.com/view /index.html, 它的域为:baidu.com。这里不做详述,后面的章节会有所涉及。
Path, 可选,指明了Cookie在有效域中的有效路径,在有效路径外的网页不可以读写Cookie,默认的是产生此Cookie的信息的URL;而该属性也是 Cookie的另一个安全特征,限制对Web服务器上特定目录的访问。即控制哪些访问能触发发送。例如请求的地址是上面的URL,如果 path=/view,这个Cookie就会被发送,但是path为其他路径的话,该Cookie会被忽略。
Secure, 可选,一个true/false值,用于表示Cookie是否只能从安全网站(使用SSL和https协议的网站)中访问;即如果标记一个Cookie为 安全的(这个值被设置为true),那么仅当客户端与服务器的对话通道是安全的(如HTTP over SSL),Cookie才会被传送。
Expire Date, 可选,指明了Cookie的有效时间,一旦过期,Cookie将不再有效,通常由产生Cookie的程序(Date由服务器指明)指定,如果不指明,系统会默认Cookie将在用户会话结束后自动过期。

Path – 路径。指定与cookie关联的WEB页。值可以是一个目录,或者是一个路径。如果http://www.jzxue.com/html/java/建立了一个cookie,那么在http://www.jzxue.com/html/java/目录里的所有页面,以及该目录下面任何子目录里的页面都可以访问这个cookie。这就是说,在http://www.jzxue.com/html/java/stories/articles 里的任何页面都可以访问http://www.jzxue.com/html/java/index.html建立的cookie。但是,如果http://www.jzxue.com/html/asp/ 需要访问http://www.jzxue.com/html/java/index.html设置的cookes,该怎么办?这时,我们要把cookies 的path属性设置成“/”。在指定路径的时候,凡是来自同一服务器,URL里有相同路径的所有WEB页面都可以共享cookies。现在看另一个例子:如果想让 http://www.jzxue.com/devhead/filters/ 和http://www.jzxue.com/devhead/stories/共享cookies,就要把path设成“/devhead”。

Domain – 域。指定关联的WEB服务器或域。值是域名,比如jzxue.com。这是对path路径属性的一个延伸。如果我们想让 catalog.mycompany.com 能够访问shoppingcart.mycompany.com设置的cookies,该怎么办? 我们可以把domain属性设置成“mycompany.com”,并把path属性设置成“/”。FYI:不能把cookies域属性设置成与设置它的服务器的所在域不同的值。

Secure – 安全。指定cookie的值通过网络如何在用户和WEB服务器之间传递。这个属性的值或者是“secure”,或者为空。缺省情况下,该属性为空,也就是使用不安全的HTTP连接传递数据。如果一个 cookie 标记为secure,那么,它与WEB服务器之间就通过HTTPS或者其它安全协议传递数据。不过,设置了secure属性不代表其他人不能看到你机器本地保存的cookie。换句话说,把cookie设置为secure,只保证cookie与WEB服务器之间的数据传输过程加密,而保存在本地的cookie文件并不加密。如果想让本地cookie也加密,得自己加密数据。


Session的机制

Session是存放在服务器端的类似于HashTable结构(每一种Web开发技术的实现可能不一样,下文直接称之为HashTable)来存放用户 数据,当浏览器第一次发送请求时,服务器自动生成了一个HashTable和一个Session ID用来唯一标识这个HashTable,并将其通过响应发送到浏览器。当浏览器第二次发送请求,会将前一次服务器响应中的Session ID放在请求中一并发送到服务器上,服务器从请求中提取出Session ID,并和保存的所有Session ID进行对比,找到这个用户对应的HashTable。

一般情况下,服务器会在一定时间内(默认20分钟)保存这个HashTable,过了时间限制,就会销毁这个HashTable。在销毁之前,程序员可以 将用户的一些数据以Key和Value的形式暂时存放在这个HashTable中。当然,也有使用数据库将这个HashTable序列化后保存起来的,这 样的好处是没了时间的限制,坏处是随着时间的增加,这个数据库会急速膨胀,特别是访问量增加的时候。一般还是采取前一种方式,以减轻服务器压力。

Session的客户端实现形式(即Session ID的保存方法)

一般浏览器提供了两种方式来保存,还有一种是程序员使用HTML隐藏域的方式自定义实现:

[1] 使用Cookie来保存,这是最常见的方法,本文“记住我的登录状态”功能的实现正式基于这种方式的。服务器通过设置Cookie的方式将Session ID发送到浏览器。如果我们不设置这个过期时间,那么这个Cookie将不存放在硬盘上,当浏览器关闭的时候,Cookie就消失了,这个Session ID就丢失了。如果我们设置这个时间为若干天之后,那么这个Cookie会保存在客户端硬盘中,即使浏览器关闭,这个值仍然存在,下次访问相应网站时,同 样会发送到服务器上。

[2] 使用URL附加信息的方式,也就是像我们经常看到JSP网站会有aaa.jsp?JSESSIONID=*一样的。这种方式和第一种方式里面不设置 Cookie过期时间是一样的。

[3] 第三种方式是在页面表单里面增加隐藏域,这种方式实际上和第二种方式一样,只不过前者通过GET方式发送数据,后者使用POST方式发送数据。但是明显后 者比较麻烦。

session什么时候被创建
  一个常见的错误是以为session在有客户端访问时就被创建,然而事实是直到某server端程序(如Servlet)调用HttpServletRequest.getSession(true)这样的语句时才会被创建。
、session何时被删除
session在下列情况下被删除:
A.程序调用HttpSession.invalidate()
B.距离上一次收到客户端发送的session id时间间隔超过了session的最大有效时间
C.服务器进程被停止
  再次注意关闭浏览器只会使存储在客户端浏览器内存中的session cookie失效,不会使服务器端的session对象失效。

实现“记住我的登录状态”的功能

前面我们了解到,如果我们将Session ID通过Cookie发送到客户端的时候设置其过期时间为1年,那么在今后的一年时间内,客户端访问我的网站的时候都回将这个Session ID值发送到服务器上,服务器根据这个Session ID从内存或者数据库里面恢复存放Key-Value对的Hashtable。

其实这已经很好的实现了我们的功能了。但是,前面也提到了,实际上Session并不会一直都存在的,过了一定的时间之后,服务器上的Session就被 销毁了,以减轻服务器的访问压力。当服务器上的数据被销毁后,即使客户端上存放了Cookie也没有办法“记住我的登录状态”了。

通用的实现办法是,将用户的用户名和加密之后的密码也通过Cookie的方式存放在客户端,当服务器上的Session销毁以后,使用Cookie里面存 放的用户名和加密之后的密码重新执行一次登录操作,重建Session,并更新客户端上Cookie中存放的的Session ID,而这个操作是发生在用户请求一个需要身份验证的页面资源的背后,对于用户来讲是透明的,于是就达到了“记住我的登录状态”的目的了。


SessionID的本质

一、客户端用cookie保存了sessionID(也就是上文提到的保存sessionid的A方式)


客户端用cookie保存了sessionID,当我们请求服务器的时候,会把这个sessionID一起发给服务器,服务器会到内存中搜索对应的sessionID,如果找到了对应的 sessionID,说明我们处于登录状态,有相应的权限;如果没有找到对应的sessionID,这说明:要么是我们把浏览器关掉了(后面会说明为什 么),要么session超时了(没有请求服务器超过20分钟),session被服务器清除了,则服务器会给你分配一个新的sessionID。你得重 新登录并把这个新的sessionID保存在cookie中。 
在没有把浏览器关掉的时候(这个时候假如已经把sessionID保存在cookie中了)这个sessionID会一直保存在浏览器中,每次请求的时候都会把这个sessionID提交到服务器,所以服务器认为我们是登录的;当然,如果太长时间没有请求服务器,服务器会认为我们已经所以把浏览器关掉了,这个时候服务器会把该sessionID从内存中清除掉,这个时候如果我们再去请求服务器,sessionID已经不存在了,所以服务器并没有在内存中找到对应的 sessionID,所以会再产生一个新的sessionID,这个时候一般我们又要再登录一次。 

二、客户端没有用cookie保存sessionID


这 个时候如果我们请求服务器,因为没有提交sessionID上来,服务器会认为你是一个全新的请求,服务器会给你分配一个新的sessionID,这就是 为什么我们每次打开一个新的浏览器的时候(无论之前我们有没有登录过)都会产生一个新的sessionID(或者是会让我们重新登录)。 

当我们一旦把浏览器关掉后,再打开浏览器再请求该页面,它会让我们登录,这是为什么?我们明明已经登录了,而且还没有超时,sessionID肯定还在服 务器上的,为什么现在我们又要再一次登录呢?这是因为我们关掉浏览再请求的时候,我们提交的信息没有把刚才的sessionID一起提交到服务器,所以服 务器不知道我们是同一个人,所以这时服务器又为我们分配一个新的sessionID,打个比方:浏览器就好像一个要去银行开户的人,而服务器就好比银行, 这个要去银行开户的人这个时候显然没有帐号(sessionID),所以到银行后,银行工作人员问有没有帐号,他说没有,这个时候银行就会为他开通一个帐 号。所以可以这么说,每次打开一个新的浏览器去请求的一个页面的时候,服务器都会认为,这是一个新的请求,他为你分配一个新的sessionID。

总结:

cookie 和session 的区别:

1、cookie数据存放在客户的浏览器上,session数据放在服务器上。

2、cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗
   考虑到安全应当使用session。

3、session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能
   考虑到减轻服务器性能方面,应当使用COOKIE。

4、单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。

5、所以个人建议:
   将登陆信息等重要信息存放为SESSION
   其他信息如果需要保留,可以放在COOKIE中

如果用户把cookie禁止掉,是不是session也不能用了呢?禁止掉cookie后,session当然可以用,不过通过其他的方式来获得这个sessionid,比如,可以根在url的后面,或者以表单的形势提交到服务器端。从而使服务器端了解客户端的状态。

四,session和cookie谁更安全

就个人而言,我觉得session更安全一点,我以下几点看法。

1,如果session和cookie一样安全的话,二者就没有并要同时存在了,只要cookie就好了,让客户端来分提服务器的负担,并且对于用户来说又是透明的。何乐而不为呢。

2,session的sessionID是放在cookie里,要想功破session的话,第一要功破cookie。功破cookie后,你要得到 sessionID,sessionID是要有人登录,或者启动session_start才会有,你不知道什么时候会有人登录。第二,sessionID是加密的,第二次session_start的时候,前一次的sessionID就没有用了,session过期时sessionid也会失效,想在短时间内功破加了密的 sessionID很难。session是针对某一次通信而言,会话结束session也就随着消失了,而真正的cookie存在于客户端硬盘上的一个文本文件,谁安全很显然了。

3,如果session这么容易被功破,这么不安全的话,我想现有的绝大部分网站都不安全了。


Session 是一种服务器端技术, Session 对象在服务器端创建,通常采用散列表来存储信息,例如, Tomcat 的 Session 实现采用 HashMap 对象来存储属性名和属性值。

Cookie是由 Netscape 公司发明的、用于跟踪用户会话的一种方式。 Cookie 是由服务器发送给客户的片段信息,存储在客户端浏览器的内存中或硬盘上,在客户随后对该服务器的请求中发回它。

Cookie小结

① Cookie在服务端创建 Cookie cookie = new Cookie(name,value);

② Cookie是保存在浏览器这端 response.addCookie(cookie);

③ Cookie的生命周期可以通过cookie.setMaxAge(int second)来设置 Cookie默认生命周期是会话级别(即存储在浏览器的内存中) 如果没有设置setMaxAge()则该cookie的生命周期当浏览器关闭时就挂了,setMaxAge(0) +response.addCookie(cookie),相当于删除Cookie 此时如果cookie文件内部只有该Cookie则,文件也一并删除;否则只删除该Cookie

④ Cookie可以被多个浏览器共享

⑤ 一个web应用可以保存多个cookie(放置在同一个文件内部) ,最多不要超过20个,每个Cookie的大小限制为4kB,因此Cookie不会塞满你的硬盘更不会被作为"拒绝服务"的攻击手段。浏览器一般保存的Cookie不会超过300个

⑥ Cookie存放中文,出现的乱码问题 存放String val = java.net.URLEncoder.encode("中文名称","utf-8"); Cookie cookie = new Cookie("name","val"); 读出 String val = java.net.URLDecoder.decode

(cookie.getValue("name"),"utf-8"); out.println("name="+val)

session小结:

① Session是存放在服务器的内存中

② 一个用户浏览器,独享一个session域对象

③ Session中的属性的默认生命周期是30min,可以通过web.xml来修改

④ Session中可以存放多个属性(包括对象)

⑤ 如果session.setAttribute(name,value);中name相同,则会替换掉。

Session VS Cookie :

1.存储位置不同: Cookie存在在客户端(临时文件夹) Session存在服务器内存中,一个session域对象为一个用户浏览器服务

2.安全性: Cookie以明文方式存放在客户端,安全较弱,可以通过MD5加密算法在存放 Session存放在服务器端内存中,所以安全性较好

3.网络传输量: Cookie会传递信息给服务器 Session的属性值不会给客户端

4.生命周期: Cookie的声明周期是累计时间 Session的生命周期是访问session的间隔时间,在一些情况下session也会失效关闭tomcat,reload web应用,时间到,调用invalidate()[安全退出]

5.从访问范围 :Session为一个浏览器独享 Cookie为多个用户浏览器共享 因为session会占用服务器的内存,因此不要向session存放过多、过大的对象,会影响性能。


参考:http://blog.chinaunix.net/uid-17102734-id-3436650.html

http://jiyuede.blog.163.com/blog/static/332519212013830111053697/

http://www.cnblogs.com/aspnet_csharp/archive/2012/10/18/2729609.html

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值