cookie和session详解

  cookie和session是javaweb中非常重要的两个技术,我认为它们是分别在浏览器端和服务器端的两个存储机制。session是服务器端的技术,cookie是浏览器端的技术,相比较而言,因为session的位置关系,所以拥有更安全,容量更大的优点。所以我们一般用cookie来存储a,记录用户的使用习惯b,网页换肤c,自动登录d,购物车(与session技术配置使用)等,比较小的东西,cookie不会超过4k,20个。这个是之前的限制,现在好像是不再正确了。

  Microsoft指出InternetExplorer8增加cookie限制为每个域名50个,但IE7似乎也允许每个域名50个cookie。

  Firefox每个域名cookie限制为50个。

  Opera每个域名cookie限制为30个。

  Safari/WebKit貌似没有cookie限制。但是如果cookie很多,则会使header大小超过服务器的处理的限制,会导致错误发生。所以cookie具体的使用限制还要看使用的浏览器而定。

  而cookie的不安全的问题,也可以通过加密来解决,这里就不加展开讲。cookie和session通过http协议在浏览器和服务器之间进行交互,什么是cookie,浏览器访问某个服务器时,服务器会创建一部分数据(以消息头set-cookie的方式)发送给浏览器,浏览器会将这一部分数据保存下来。当浏览器再访问服务器的时候,会将这部分数据发送给服务器,通过这种方式,服务器可以维护用户的状态,在客户端(浏览器)维护用户状态的一种状态管理技术。什么是session,在服务器端维护用户状态的一种状态管理技术。浏览器访问服务器的时候,服务器会创建一个对象(session对象),同时还会生成一个标识该对象的一个唯一字符串(sessionId),服务器在默认的情况下,使用cookie机制将sessionId发送浏览器。浏览器下次访问服务器时,会将sessionId携带给服务器,服务器会使用sessionId查找对应的session对象。通过这种方式来维护用户的状态,一般情况下, 服务器会在一定时间内(默认30分钟)保存这个session,过了时间限制就会销毁这个session,在销毁之前,程序员可以将用户的一些数据以key-value的形式暂时存放在这个session中 ,或者将session序列化后保存在数据库里,这样的好处是没了时间限制,坏处是随着时间的增加,这个数据库会急速膨胀,特别是访问量增加的时候,所以一般还是采用第一种方式,设置时间。至于为什么设置时间呢?因为cookie有两种形式,一种是临时的cookie(会话cookie),还有一种是持久的cookie。临时cookie生命周期是浏览器会话期间,把网页关闭,cookie就销毁了,所以再打开浏览器访问服务器时,就不会携带sessionid,就再也无法访问到这一个对应的session。而是创建一个新的session,set-cookie,如果不加一个时间限制,那么无头的session就会越来越多,对服务器形成压力,所以默认了一个半小时的销毁时间。而持久的cookie是设置了过期时间,只要没过期,关闭浏览器,cookie会保存在硬盘中,浏览器关闭,或者计算机重启,cookie依然存在,直到失效。

cookie过期时间设置方式:

cookie.setMaxAge(0);//不记录cookie/删除

cookie.setMaxAge(-1);//会话级cookie,关闭浏览器失效

cookie.setMaxAge(60*60);//过期时间为1小时

既然讲了cookie的过期时间,再补充一下session的过期时间:

具体设置的方法有三种:
1.在web容器中设置(以tomcat为例)
在tomcat-7.0confweb.xml中设置,以下是tomcat7.0中默认配置:

1
2
3
<session-config>
<session-timeout>30</session-timeout>
</session-config>

tomcat默认session超时时间为30分钟,可以根据需要修改,负数或0为不限制session失效时间

这里要注意这个session设置的时间是根据服务器来计算的,而不是客户端。所以如果在调试程序,应该是修改服务器端时间来测试,而不是客户端

2.在工程的web.xml中设置
<!--时间单位为分钟-->

1
2
3
<session-config>
<session-timeout>15</session-timeout>
</session-config>

 这里的15是指15分钟失效

3.通过java代码设置
session.setMaxInactiveInterval(30*60);//以秒为单位,即在没有活动30分钟后,session将失效

三种方式优先等级:1 < 2 < 3

cookies给网站和用户带来的好处非常多: 
1、Cookie能使站点跟踪特定访问者的访问次数、最后访问时间和访问者进入站点的路径 
2、Cookie能告诉在线广告商广告被点击的次数,从而可以更精确的投放广告 
3、Cookie有效期限未到时,Cookie能使用户在不键入密码和用户名的情况下进入曾经浏览过的一些站点 
4、Cookie能帮助站点统计用户个人资料以实现各种各样的个性化服务 

而sessionId在客户端的保存方法,有三种,浏览器有两种,程序员使用html隐藏域是第三种

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

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

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

cookie和session保存用户信息的区别:

简 单的说,当你登录一个网站的时候,如果web服务器端使用的是session,那么所有的数据都保存在服务器上面,客户端每次请求服务器的时候会发送 当前会话的sessionid,服务器根据当前sessionid判断相应的用户数据标志,以确定用户是否登录,或具有某种权限。由于数据是存储在服务器 上面,所以你不能伪造,但是如果你能够获取某个登录用户的sessionid,用特殊的浏览器伪造该用户的请求也是能够成功的。sessionid是服务 器和客户端链接时候随机分配的,一般来说是不会有重复,但如果有大量的并发请求,也不是没有重复的可能性,我曾经就遇到过一次。登录某个网站,开始显示的 是自己的信息,等一段时间超时了,一刷新,居然显示了别人的信息。

如果浏览器使用的是 cookie,那么所有的数据都保存在浏览器端,比如你登录以后,服务器设置了 cookie用户名(username),那么,当你再次请求服务器的时候,浏览器会将username一块发送给服务器,这些变量有一定的特殊标记。服 务器会解释为 cookie变量。所以只要不关闭浏览器,那么 cookie变量便一直是有效的,所以能够保证长时间不掉线。如果你能够截获某个用户的 cookie变量,然后伪造一个数据包发送过去,那么服务器还是认为你是合法的。所以,使用 cookie被攻击的可能性比较大。如果设置了的有效时间,那么它会将 cookie保存在客户端的硬盘上,下次再访问该网站的时候,浏览器先检查有没有 cookie,如果有的话,就读取该 cookie,然后发送给服务器。如果你在机器上面保存了某个论坛 cookie,有效期是一年,如果有人入侵你的机器,将你的 cookie拷走,然后放在他的浏览器的目录下面,那么他登录该网站的时候就是用你的的身份登录的。所以 cookie是可以伪造的。当然,伪造的时候需要主意,直接copy cookie文件到 cookie目录,浏览器是不认的,他有一个index.dat文件,存储了 cookie文件的建立时间,以及是否有修改,所以你必须先要有该网站的 cookie文件,并且要从保证时间上骗过浏览器,曾经在学校的vbb论坛上面做过试验,copy别人的 cookie登录,冒用了别人的名义发帖子,完全没有问题。

Session是由应用服务器维持的一个服务器端的存储空间,用户在连接服务器时,会由服务器生成一个唯一的SessionID,用该SessionID 为标识符来存取服务器端的Session存储空间。而SessionID这一数据则是保存到客户端,用Cookie保存的,用户提交页面时,会将这一 SessionID提交到服务器端,来存取Session数据。这一过程,是不用开发人员干预的。所以一旦客户端禁用Cookie,那么Session也会失效。

服务器也可以通过URL重写的方式来传递SessionID的值,因此不是完全依赖Cookie。如果客户端Cookie禁用,则服务器可以自动通过重写URL的方式来保存Session的值,并且这个过程对程序员透明。

可以试一下,即使不写Cookie,在使用request.getCookies();取出的Cookie数组的长度也是1,而这个Cookie的名字就是JSESSIONID,还有一个很长的二进制的字符串,是SessionID的值。

cookie和session的区别和联系:

Cookies是属于Session对象的一种。但有不同,Cookies不会占服务器资源,是存在客服端内存或者一个cookie的文本文件中;而“Session”则会占用服务器资源。所以,尽量不要使用Session,而使用Cookies。但是我们一般认为cookie是不可靠的,session是可靠地,但是目前很多著名的站点也都以来cookie。有时候为了解决禁用cookie后的页面处理,通常采用url重写技术,调用session中大量有用的方法从session中获取数据后置入页面。

Cookies与Session的应用场景: 
Cookies的安全性能一直是倍受争议的。虽然Cookies是保存在本机上的,但是其信息的完全可见性且易于本地编辑性,往往可以引起很多的安全问题。所以Cookies到底该不该用,到底该怎样用,就有了一个需要给定的底线。

先来看看,网站的敏感数据有哪些。

登陆验证信息。一般采用Session(“Logon”)=true or false的形式。 
用户的各种私人信息,比如姓名等,某种情况下,需要保存在Session里 
需要在页面间传递的内容信息,比如调查工作需要分好几步。每一步的信息都保存在Session里,最后在统一更新到数据库。

当然还会有很多,这里列举一些比较典型的 
假如,一个人孤僻到不想碰Session,因为他认为,如果用户万一不小心关闭了浏览器,那么之前保存的数据就全部丢失了。所以,他出于好意,决定把这些用Session的地方,都改成用Cookies来存储,这完全是可行的,且基本操作和用Session一模一样。那么,下面就针对以上的3个典型例子,做一个分析 
很显然,只要某个有意非法入侵者,知道该网站验证登陆信息的Session变量是什么,那么他就可以事先编辑好该Cookies,放入到Cookies目录中,这样就可以顺利通过验证了。这是不是很可怕? 
Cookies完全是可见的,即使程序员设定了Cookies的生存周期(比如只在用户会话有效期内有效),它也是不安全的。假设,用户忘了关浏览器 或者一个恶意者硬性把用户给打晕,那用户的损失将是巨大的。 
这点如上点一样,很容易被它人窃取重要的私人信息。但,其还有一个问题所在是,可能这些数据信息量太大,而使得Cookies的文件大小剧增。这可不是用户希望所看到的。

显然,Cookies并不是那么一块好啃的小甜饼。但,Cookies的存在,当然有其原因。它给予程序员更多发挥编程才能的空间。所以,使用Cookies改有个底线。这个底线一般来说,遵循以下原则。 
不要保存私人信息。 
任何重要数据,最好通过加密形式来保存数据(最简单的可以用URLEncode,当然也可以用完善的可逆加密方式,遗憾的是,最好不要用md5来加密)。 
是否保存登陆信息,需有用户自行选择。 
长于10K的数据,不要用到Cookies。 
也不要用Cookies来玩点让客户惊喜的小游戏。

cookie的具体使用:

cookie的使用
a,创建:
Cookie cookie = new Cookie(String name,
String value);
response.addCookie(cookie);
b,cookie的生存时间
在默认情况下,cookie会保存在内存(浏览器所维护的一块内存空间)当中。所以,当浏览器关闭,cookie会丢失。
可以设置cookie的生存时间
Cookie.setMaxAge(int seconds);
seconds > 0 : 即使浏览器关闭,cookie会以文件的方式保存在硬盘上。
seconds < 0: 默认(即保存在内存里)
seconds = 0: 删除。
c,编码问题
cookie的值只能是ascii字符,所以对于中文,可以将其转换成ascii字符的表示。我们可以在保存cookie的值时,使用String URLEncoder.encode("张三","utf-8");读取cookie值时,使用URLDecoder.decode()。

d,查询
Cookie[] cookies = request.getCookies();
如果找不到任何的cookie,返回null。
String Cookie.getName();
String Cookie.getValue();

f,路径问题

http://ip:port/appname/jsp01/jsp01.jsp当中,有Cookie c = new Cookie();在创建一个cookie时,都会有一个默认的path,该值是创建该cookie的组件的地址。此时,该path是 /appname/jsp01;浏览器在访问服务器时,会比较要访问的地址addr1和cookie的path,只有path >=addr1,浏览器才会将cookie携带给服务器。


可以使用
cookie.setPath("")来修改cookie的path。
cookie.setPath("/appname"):
访问appname下的所有组件都会携带对应的cookie

cookie.setPath("/")。
访问同一个服务器内部的所有应用,都会携带对应的cookie

如果设置了cookie的域,即
cookie.setDomain(".chinesecio.com");

则浏览器会先比较要访问的地址的域名是否匹配,然后再比较path;如果只设置域名的话,一级域名是chinesecio的地址都可以共享cookie。

原文地址:https://www.cnblogs.com/jiangshengxiang/p/8420698.html