Cookie与Session机制详解.docx

上传人:b****6 文档编号:7985172 上传时间:2023-05-12 格式:DOCX 页数:28 大小:149.14KB
下载 相关 举报
Cookie与Session机制详解.docx_第1页
第1页 / 共28页
Cookie与Session机制详解.docx_第2页
第2页 / 共28页
Cookie与Session机制详解.docx_第3页
第3页 / 共28页
Cookie与Session机制详解.docx_第4页
第4页 / 共28页
Cookie与Session机制详解.docx_第5页
第5页 / 共28页
Cookie与Session机制详解.docx_第6页
第6页 / 共28页
Cookie与Session机制详解.docx_第7页
第7页 / 共28页
Cookie与Session机制详解.docx_第8页
第8页 / 共28页
Cookie与Session机制详解.docx_第9页
第9页 / 共28页
Cookie与Session机制详解.docx_第10页
第10页 / 共28页
Cookie与Session机制详解.docx_第11页
第11页 / 共28页
Cookie与Session机制详解.docx_第12页
第12页 / 共28页
Cookie与Session机制详解.docx_第13页
第13页 / 共28页
Cookie与Session机制详解.docx_第14页
第14页 / 共28页
Cookie与Session机制详解.docx_第15页
第15页 / 共28页
Cookie与Session机制详解.docx_第16页
第16页 / 共28页
Cookie与Session机制详解.docx_第17页
第17页 / 共28页
Cookie与Session机制详解.docx_第18页
第18页 / 共28页
Cookie与Session机制详解.docx_第19页
第19页 / 共28页
Cookie与Session机制详解.docx_第20页
第20页 / 共28页
亲,该文档总共28页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

Cookie与Session机制详解.docx

《Cookie与Session机制详解.docx》由会员分享,可在线阅读,更多相关《Cookie与Session机制详解.docx(28页珍藏版)》请在冰点文库上搜索。

Cookie与Session机制详解.docx

Cookie与Session机制详解

Cookie/Session机制详解

会话(Session)跟踪是Web程序中常用的技术,用来跟踪用户的整个会话。

常用的会话跟踪技术是Cookie与Session。

Cookie通过在客户端记录信息确定用户身份,Session通过在服务器端记录信息确定用户身份。

本章将系统地讲述Cookie与Session机制,并比较说明什么时候不能用Cookie,什么时候不能用Session。

1.1 Cookie机制

在程序中,会话跟踪是很重要的事情。

理论上,一个用户的所有请求操作都应该属于同一个会话,而另一个用户的所有请求操作则应该属于另一个会话,二者不能混淆。

例如,用户A在超市购买的任何商品都应该放在A的购物车内,不论是用户A什么时间购买的,这都是属于同一个会话的,不能放入用户B或用户C的购物车内,这不属于同一个会话。

而Web应用程序是使用HTTP协议传输数据的。

HTTP协议是无状态的协议。

一旦数据交换完毕,客户端与服务器端的连接就会关闭,再次交换数据需要建立新的连接。

这就意味着服务器无法从连接上跟踪会话。

即用户A购买了一件商品放入购物车内,当再次购买商品时服务器已经无法判断该购买行为是属于用户A的会话还是用户B的会话了。

要跟踪该会话,必须引入一种机制。

Cookie就是这样的一种机制。

它可以弥补HTTP协议无状态的不足。

在Session出现之前,基本上所有的网站都采用Cookie来跟踪会话。

1.1.1 什么是Cookie

Cookie意为“甜饼”,是由W3C组织提出,最早由Netscape社区发展的一种机制。

目前Cookie已经成为标准,所有的主流浏览器如IE、Netscape、Firefox、Opera等都支持Cookie。

由于HTTP是一种无状态的协议,服务器单从网络连接上无从知道客户身份。

怎么办呢?

就给客户端们颁发一个通行证吧,每人一个,无论谁访问都必须携带自己通行证。

这样服务器就能从通行证上确认客户身份了。

这就是Cookie的工作原理。

Cookie实际上是一小段的文本信息。

客户端请求服务器,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个Cookie。

客户端浏览器会把Cookie保存起来。

当浏览器再请求该网站时,浏览器把请求的网址连同该Cookie一同提交给服务器。

服务器检查该Cookie,以此来辨认用户状态。

服务器还可以根据需要修改Cookie的内容。

 

查看某个网站颁发的Cookie很简单。

在浏览器地址栏输入javascript:

alert(document.cookie)就可以了(需要有网才能查看)。

JavaScript脚本会弹出一个对话框显示本网站颁发的所有Cookie的内容,如图1.1所示。

图1.1 Baidu网站颁发的Cookie

图1.1中弹出的对话框中显示的为Baidu网站的Cookie。

其中第一行BAIDUID记录的就是笔者的身份helloweenvsfei,只是Baidu使用特殊的方法将Cookie信息加密了。

注意:

Cookie功能需要浏览器的支持。

如果浏览器不支持Cookie(如大部分手机中的浏览器)或者把Cookie禁用了,Cookie功能就会失效。

不同的浏览器采用不同的方式保存Cookie。

IE浏览器会在“C:

\DocumentsandSettings\你的用户名\Cookies”文件夹下以文本文件形式保存,一个文本文件保存一个Cookie。

1.1.2 记录用户访问次数

Java中把Cookie封装成了javax.servlet.http.Cookie类。

每个Cookie都是该Cookie类的对象。

服务器通过操作Cookie类对象对客户端Cookie进行操作。

通过request.getCookie()获取客户端提交的所有Cookie(以Cookie[]数组形式返回),通过response.addCookie(Cookiecookie)向客户端设置Cookie。

Cookie对象使用key-value属性对的形式保存用户状态,一个Cookie对象保存一个属性对,一个request或者response同时使用多个Cookie。

因为Cookie类位于包javax.servlet.http.*下面,所以JSP中不需要import该类。

1.1.3 Cookie的不可跨域名性

很多网站都会使用Cookie。

例如,Google会向客户端颁发Cookie,Baidu也会向客户端颁发Cookie。

那浏览器访问Google会不会也携带上Baidu颁发的Cookie呢?

或者Google能不能修改Baidu颁发的Cookie呢?

答案是否定的。

Cookie具有不可跨域名性。

根据Cookie规范,浏览器访问Google只会携带Google的Cookie,而不会携带Baidu的Cookie。

Google也只能操作Google的Cookie,而不能操作Baidu的Cookie。

Cookie在客户端是由浏览器来管理的。

浏览器能够保证Google只会操作Google的Cookie而不会操作Baidu的Cookie,从而保证用户的隐私安全。

浏览器判断一个网站是否能操作另一个网站Cookie的依据是域名。

Google与Baidu的域名不一样,因此Google不能操作Baidu的Cookie。

需要注意的是,虽然网站与网站同属于Google,但是域名不一样,二者同样不能互相操作彼此的Cookie。

注意:

用户登录网站之后会发现访问时登录信息仍然有效,而普通的Cookie是做不到的。

这是因为Google做了特殊处理。

本章后面也会对Cookie做类似的处理。

1.1.4 Unicode编码:

保存中文

中文与英文字符不同,中文属于Unicode字符,在内存中占4个字符,而英文属于ASCII字符,内存中只占2个字节。

Cookie中使用Unicode字符时需要对Unicode字符进行编码,否则会乱码。

提示:

Cookie中保存中文只能编码。

一般使用UTF-8编码即可。

不推荐使用GBK等中文编码,因为浏览器不一定支持,而且JavaScript也不支持GBK编码。

1.1.5 BASE64编码:

保存二进制图片

Cookie不仅可以使用ASCII字符与Unicode字符,还可以使用二进制数据。

例如在Cookie中使用数字证书,提供安全度。

使用二进制数据时也需要进行编码。

%注意:

本程序仅用于展示Cookie中可以存储二进制内容,并不实用。

由于浏览器每次请求服务器都会携带Cookie,因此Cookie内容不宜过多,否则影响速度。

Cookie的内容应该少而精。

1.1.6 设置Cookie的所有属性

除了name与value之外,Cookie还具有其他几个常用的属性。

每个属性对应一个getter方法与一个setter方法。

Cookie类的所有属性如表1.1所示。

表1.1 Cookie常用属性

属 性 名

描   述

Stringname

该Cookie的名称。

Cookie一旦创建,名称便不可更改

Objectvalue

该Cookie的值。

如果值为Unicode字符,需要为字符编码。

如果值为二进制数据,则需要使用BASE64编码

intmaxAge

该Cookie失效的时间,单位秒。

如果为正数,则该Cookie在maxAge秒之后失效。

如果为负数,该Cookie为临时Cookie,关闭浏览器即失效,浏览器也不会以任何形式保存该Cookie。

如果为0,表示删除该Cookie。

默认为–1

booleansecure

该Cookie是否仅被使用安全协议传输。

安全协议。

安全协议有HTTPS,SSL等,在网络上传输数据之前先将数据加密。

默认为false

Stringpath

该Cookie的使用路径。

如果设置为“/sessionWeb/”,则只有contextPath为“/sessionWeb”的程序可以访问该Cookie。

如果设置为“/”,则本域名下contextPath都可以访问该Cookie。

注意最后一个字符必须为“/”

Stringdomain

可以访问该Cookie的域名。

如果设置为“”,则所有以“”结尾的域名都可以访问该Cookie。

注意第一个字符必须为“.”

Stringcomment

该Cookie的用处说明。

浏览器显示Cookie信息的时候显示该说明

intversion

该Cookie使用的版本号。

0表示遵循Netscape的Cookie规范,1表示遵循W3C的RFC2109规范

1.1.7 Cookie的有效期

Cookie的maxAge决定着Cookie的有效期,单位为秒(Second)。

Cookie中通过getMaxAge()方法与setMaxAge(intmaxAge)方法来读写maxAge属性。

如果maxAge属性为正数,则表示该Cookie会在maxAge秒之后自动失效。

浏览器会将maxAge为正数的Cookie持久化,即写到对应的Cookie文件中。

无论客户关闭了浏览器还是电脑,只要还在maxAge秒之前,登录网站时该Cookie仍然有效。

下面代码中的Cookie信息将永远有效。

Cookiecookie=newCookie("username","helloweenvsfei");  //新建Cookie

cookie.setMaxAge(Integer.MAX_VALUE);         //设置生命周期为MAX_VALUE

response.addCookie(cookie);               //输出到客户端

如果maxAge为负数,则表示该Cookie仅在本浏览器窗口以及本窗口打开的子窗口内有效,关闭窗口后该Cookie即失效。

maxAge为负数的Cookie,为临时性Cookie,不会被持久化,不会被写到Cookie文件中。

Cookie信息保存在浏览器内存中,因此关闭浏览器该Cookie就消失了。

Cookie默认的maxAge值为–1。

如果maxAge为0,则表示删除该Cookie。

Cookie机制没有提供删除Cookie的方法,因此通过设置该Cookie即时失效实现删除Cookie的效果。

失效的Cookie会被浏览器从Cookie文件或者内存中删除,

例如:

Cookiecookie=newCookie("username","helloweenvsfei");  //新建Cookie

cookie.setMaxAge(0);                     //设置生命周期为0,不能为负数

response.addCookie(cookie);               //必须执行这一句

response对象提供的Cookie操作方法只有一个添加操作add(Cookiecookie)。

要想修改Cookie只能使用一个同名的Cookie来覆盖原来的Cookie,达到修改的目的。

删除时只需要把maxAge修改为0即可。

注意:

从客户端读取Cookie时,包括maxAge在内的其他属性都是不可读的,也不会被提交。

浏览器提交Cookie时只会提交name与value属性。

maxAge属性只被浏览器用来判断Cookie是否过期。

1.1.8 Cookie的修改、删除

Cookie并不提供修改、删除操作。

如果要修改某个Cookie,只需要新建一个同名的Cookie,添加到response中覆盖原来的Cookie。

如果要删除某个Cookie,只需要新建一个同名的Cookie,并将maxAge设置为0,并添加到response中覆盖原来的Cookie。

注意是0而不是负数。

负数代表其他的意义。

读者可以通过上例的程序进行验证,设置不同的属性。

注意:

修改、删除Cookie时,新建的Cookie除value、maxAge之外的所有属性,例如name、path、domain等,都要与原Cookie完全一样。

否则,浏览器将视为两个不同的Cookie不予覆盖,导致修改、删除失败。

1.1.9 Cookie的域名

Cookie是不可跨域名的。

域名颁发的Cookie不会被提交到域名去。

这是由Cookie的隐私安全机制决定的。

隐私安全机制能够禁止网站非法获取其他网站的Cookie。

正常情况下,同一个一级域名下的两个二级域名如和也不能交互使用Cookie,因为二者的域名并不严格相同。

如果想所有名下的二级域名都可以使用该Cookie,需要设置Cookie的domain参数,例如:

Cookiecookie=newCookie("time","20080808");//新建Cookie

cookie.setDomain("");         //设置域名

cookie.setPath("/");                        //设置路径

cookie.setMaxAge(Integer.MAX_VALUE);            //设置有效期

response.addCookie(cookie);                  //输出到客户端

读者可以修改本机C:

\WINDOWS\system32\drivers\etc下的hosts文件来配置多个临时域名,然后使用setCookie.jsp程序来设置跨域名Cookie验证domain属性。

注意:

domain参数必须以点(".")开始。

另外,name相同但domain不同的两个Cookie是两个不同的Cookie。

如果想要两个域名完全不同的网站共有Cookie,可以生成两个Cookie,domain属性分别为两个域名,输出到客户端。

1.1.10 Cookie的路径

domain属性决定运行访问Cookie的域名,而path属性决定允许访问Cookie的路径(ContextPath)。

例如,如果只允许/sessionWeb/下的程序使用Cookie,可以这么写:

Cookiecookie=newCookie("time","20080808");   //新建Cookie

cookie.setPath("/session/");                     //设置路径

response.addCookie(cookie);                     //输出到客户端

设置为“/”时允许所有路径使用Cookie。

path属性需要使用符号“/”结尾。

name相同但domain相同的两个Cookie也是两个不同的Cookie。

注意:

页面只能获取它属于的Path的Cookie。

例如/session/test/a.jsp不能获取到路径为/session/abc/的Cookie。

使用时一定要注意。

1.1.11 Cookie的安全属性

HTTP协议不仅是无状态的,而且是不安全的。

使用HTTP协议的数据不经过任何加密就直接在网络上传播,有被截获的可能。

使用HTTP协议传输很机密的内容是一种隐患。

如果不希望Cookie在HTTP等非安全协议中传输,可以设置Cookie的secure属性为true。

浏览器只会在HTTPS和SSL等安全协议中传输此类Cookie。

下面的代码设置secure属性为true:

Cookiecookie=newCookie("time","20080808");//新建Cookie

cookie.setSecure(true);                     //设置安全属性

response.addCookie(cookie);                  //输出到客户端

提示:

secure属性并不能对Cookie内容加密,因而不能保证绝对的安全性。

如果需要高安全性,需要在程序中对Cookie内容加密、解密,以防泄密。

1.1.12 JavaScript操作Cookie

Cookie是保存在浏览器端的,因此浏览器具有操作Cookie的先决条件。

浏览器可以使用脚本程序如JavaScript或者VBScript等操作Cookie。

这里以JavaScript为例介绍常用的Cookie操作。

例如下面的代码会输出本页面所有的Cookie。

由于JavaScript能够任意地读写Cookie,有些好事者便想使用JavaScript程序去窥探用户在其他网站的Cookie。

不过这是徒劳的,W3C组织早就意识到JavaScript对Cookie的读写所带来的安全隐患并加以防备了,W3C标准的浏览器会阻止JavaScript读写任何不属于自己网站的Cookie。

换句话说,A网站的JavaScript程序读写B网站的Cookie不会有任何结果。

1.1.13 案例:

永久登录

如果用户是在自己家的电脑上上网,登录时就可以记住他的登录信息,下次访问时不需要再次登录,直接访问即可。

实现方法是把登录信息如账号、密码等保存在Cookie中,并控制Cookie的有效期,下次访问时再验证Cookie中的登录信息即可。

保存登录信息有多种方案。

最直接的是把用户名与密码都保持到Cookie中,下次访问时检查Cookie中的用户名与密码,与数据库比较。

这是一种比较危险的选择,一般不把密码等重要信息保存到Cookie中。

还有一种方案是把密码加密后保存到Cookie中,下次访问时解密并与数据库比较。

这种方案略微安全一些。

如果不希望保存密码,还可以把登录的时间戳保存到Cookie与数据库中,到时只验证用户名与登录时间戳就可以了。

这几种方案验证账号时都要查询数据库。

本例将采用另一种方案,只在登录时查询一次数据库,以后访问验证登录信息时不再查询数据库。

实现方式是把账号按照一定的规则加密后,连同账号一块保存到Cookie中。

下次访问时只需要判断账号的加密规则是否正确即可。

本例把账号保存到名为account的Cookie中,把账号连同密钥用MD1算法加密后保存到名为ssid的Cookie中。

验证时验证Cookie中的账号与密钥加密后是否与Cookie中的ssid相等。

相关代码如下:

代码1.8 loginCookie.jsp

<%@pagelanguage="java"pageEncoding="UTF-8"isErrorPage="false"%>

<%!

                                       //JSP方法

   privatestaticfinalStringKEY=":

cookie@";

                                          //密钥 

   publicfinalstaticStringcalcMD1(Stringss){//MD1加密算法

     Strings=ss==null?

"":

ss;              //若为null返回空

     charhexDigits[]={'0','1','2','3','4','1','6','7','8','9',

     'a','b','c','d','e','f'};                   //字典

     try{

      byte[]strTemp=s.getBytes();                    //获取字节

      MessageDigestmdTemp=MessageDigest.getInstance("MD1");//获取MD1

      mdTemp.update(strTemp);                         //更新数据

      byte[]md=mdTemp.digest();                  //加密

      intj=md.length;                          //加密后的长度

      charstr[]=newchar[j*2];                  //新字符串数组

      intk=0;                                //计数器k

      for(inti=0;i

       bytebyte0=md[i];

       str[k++]=hexDigits[byte0>>>4&0xf];

       str[k++]=hexDigits[byte0&0xf];

      }

      returnnewString(str);                      //加密后字符串

     }catch(Exceptione){returnnull;}

   }

%>

<%

   request.setCharacterEncoding("UTF-8");          //设置request编码

   response.setCharacterEncoding("UTF-8");      //设置response编码

   

   Stringaction=request.getParameter("action");//获取action参数

   

   if("login".equals(action)){                  //如果为login动作

      Stringaccount=request.getParameter("account");

                                          //获取account参数

      Stringpassword=request.getParameter("password");

                                          //获取password参数

      inttimeout=newInteger(request.getParameter("timeout"));

               

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 解决方案 > 学习计划

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2