Cookie/Session 机制详解

参考网址:https://blog.csdn.net/fangaoxin/article/details/6952954/

前言

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

会话跟踪是很重要的事情,一个用户的所有请求操作都应该属于同一个会话。HTTP协议是无状态的协议,一旦数据交换完毕,客户端与服务器端的连接就会庀,再次交换数据需要建立新的连接,这就意味着服务器无法从连接上跟踪会话了。要跟踪该会话,cookie和session就是这样的一种机制。

有关Cookie

由于HTTP 是一种无状态的协议,服务器单从网络连接上无从知道客户身份。就需要给客户端们颁发一个通行证,无论谁访问都必须携带自己的通行证。这样服务器就能从通行证上确认客户身份了。这就是cookie的工作原理。

Cookie实际上是一小段的文本信息。客户端请求服务器,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个cookie。客户端浏览器就会把cookie保存起来。当浏览器再请求该网站时,浏览器把请求的网址连同该cookie一同提交给服务器。服务器检查该cookie,以此来辨认用户状态。服务器还可以根据需要来修改cookie的内容。

查看某个网站颁发的cookie,在浏览器地址栏输入javascript:alert(document.cookie)就可以了

Cookie在客户端是由浏览器来管理的,cookie具有不可跨域名性

///cookie的编码

Unicode编码:保存中文

中文属于Unicode字符,在内存中占4个字符,而英文属于ASCII字符,内存中只占2个字节。Cookie中使用Unicode字符时需要对Unicode字符进行编码,否则会乱码。

Cookie中保存中文一般使用UTF-8编码即可。不推荐GBK等中文编码

BASE64:保存二进制图片

Cookie不仅可以使用ASCII字符与Unicode字符,还可以使用二进制数据。例如在cookie中使用数字证书,提高安全度,使用二进制数据时也需要进行编码。

注意:cookie的内容应该少而精

///Cookie的有效期

Cookie的maxAge决定着cookie的有效期,单位为秒(second),cookie中通过getMaxAge()方法与setMaxAge(int maxAge)方法来读写maxAge属性

If maxAge属性 == 正数,则表示该cookie会在maxAge秒后自动失效。浏览器会将maxAge为正数的cookie持久化,即写到对应的cookie文件中。无论客户关闭了浏览器还是电脑,只要还在maxAge秒之前,登录网站时该cookie仍然有效。

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

     Cookie cookie = new Cookie("username","helloweenvsfei"); // 新建Cookie 

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

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

If maxAge属性 == 负数,则表示该cookie仅在本浏览器窗口打开的子窗口内有效,关闭窗口后该cookie即失效。maxAge为负数的Cookie,为临时性Cookie,不会被持久化,不会被写到Cookie文件中。Cookie信息保存在浏览器内存中,因此关闭浏览器该Cookie就消失了。Cookie默认的maxAge值为–1。

If maxAge属性 == 0,则表示删除该cookie。Cookie机制没有提供删除cookie的方法,因此通过设置该cookie即时失效实现删除cookie的效果。失效的cookie会被浏览器从cookie文件或者内存中删除。

如下面的代码

       Cookie cookie = new Cookie("username","helloweenvsfei");   // 新建Cookie

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

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

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

要想修改Cookie只能使用一个同名的cookie来覆盖原来的cookie,达到修改的目的。删除时只需要把maxAge修改为0即可。

注意:从客户端读取Cookie时,包括maxAge在内的其他属性都是不可读的,也不会被提交。浏览器提交cookie时只会提交name和value属性。maxAge属性只被浏览器用来判断cookie是否过期。

///Cookie的修改、删除

Cookie并不提供修改、删除操作。如果要修改某个Cookie,只需要新建一个同名的Cookie,添加到response中覆盖原来的Cookie。

如果要删除某个Cookie,只需要新建一个同名的Cookie,并将maxAge设置为0,并添加到response中覆盖原来的Cookie。注意是0而不是负数。负数代表其他的意义。

注意:修改、删除Cookie时,新的Cookie除value、maxAge之外的所有属性,例如name、path、domain等,都要与原来的cookie完全一样。否则,浏览器将视为两个不同的Cookie不予覆盖,导致修改、删除失败。

///Cookie是不可以跨域名的

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

参考代码:

      Cookie cookie = new Cookie("time","20080808"); // 新建Cookie

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

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

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

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

///Cookie的路径

domain属性决定运行访问Cookie的域名,而path属性允许访问Cookie的路径(ContextPath)例如,如果只允许/SessionWeb/下的程序使用Cookie,可以这么写代码:

      Cookie cookie = new Cookie("time","20080808"); //  新建Cookie

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

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

设置为"/"时允许所有路径使用cookie,path属性需要使用符号"/"结尾

注意:页面只能获取它属于的Path的Cookie。例如/session/test/a.jsp不能获取到路径为/session/abc/的Cookie。使用时一定要注意。

///Cookie的安全属性

HTTP协议不仅是无状态的,而且是不安全的。使用HTTP协议的数据不经过任何加密就直接在网络上传播,有被截获的可能。使用HTTP协议传输很机密的内容是一种隐患。如果不希望Cookie在HTTP等非安全协议中传输,可以设置Cookie的secure属性为true。浏览器只会在HTTPS和SSL等安全协议中传输此类Cookie。下面的代码设置secure属性为true:

       Cookie cookie = new Cookie("time", "20080808"); // 新建Cookie

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

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

提示:secure属性并不能对Cookie内容加密,因而不能保证绝对的安全性。如果需要高安全性,需要在程序中对Cookie内容加密、解密,以防泄密。

///JavaScript操作Cookie

Cookie是保存在浏览器端的,因此浏览器具有操作Cookie的先决条件。浏览器可以使用脚本程序如JavaScript或者VBScript等操作Cookie。例如下面的js代码会输出本页面所有的Cookie

【<script>document.write(document.cookie);</script>】

由于JavaScript能够任意地读写Cookie,有些好事者便想使用JavaScript程序去窥探用户在其他网站的Cookie。不过这是徒劳的,W3C组织早就意识到JavaScript对Cookie的读写所带来的安全隐患并加以防备了,W3C标准的浏览器会阻止JavaScript读写任何不属于自己网站的Cookie。换句话说,A网站的JavaScript程序读写B网站的Cookie不会有任何结果。

///案例:永久登录问题

把密码加密后保存到Cookie中,下次访问时解密并与数据库比较。

如果用户是在自己家的电脑上上网,登录时就可以记住他的登录信息,下次访问时不需要再次登录,直接访问即可。实现方法是把登录信息如账号、密码等保存在Cookie中,并控制Cookie的有效期,下次访问时再验证Cookie中的登录信息即可。

保存登录信息有多种方案。最直接的是把用户名与密码都保持到Cookie中,下次访问时检查Cookie中的用户名与密码,与数据库比较。这是一种比较危险的选择,一般不把密码等重要信息保存到Cookie中

还有一种方案是把密码加密后保存到Cookie中,下次访问时解密并与数据库比较。这种方案略微安全一些。如果不希望保存密码,还可以把登录的时间戳保存到Cookie与数据库中,到时只验证用户名与登录时间戳就可以了。

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

有关Session

Session是另一种记录客户状态的机制,不同的是Cookie保存在客户端浏览器中,而Session保存在服务器上。客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上。这就是Session。客户端浏览器再次访问时只需要从该Session中查找该客户的状态就可以了。

如果说Cookie机制是通过检查客户身上的“通行证”来确定客户身份的话,那么Session机制就是通过检查服务器上的“客户明细表”来确认客户身份。Session相当于程序在服务器上建立的一份客户档案,客户来访的时候只需要查询客户档案表就可以了。

///session的登录

当多个客户端执行程序时,服务器会保存多个客户端的Session。获取Session的时候也不需要声明获取谁的Session。Session机制决定了当前客户只会获取到自己的Session,而不会获取到别人的Session。各客户的Session也彼此独立,互不可见

提示:Session的使用比Cookie方便,但是过多的Session存储在服务器内存中,会对服务器造成压力。

///session的生命周期

Session保存在服务器端。为了获得更高的存取速度,服务器一般把Session放在内存里。每个用户都会有一个独立的Session。如果Session内容过于复杂,当大量客户访问服务器时可能会导致内存溢出。因此,Session里的信息应该尽量精简。

Session在用户第一次访问服务器的时候自动创建。需要注意只有访问JSP、Servlet等程序时才会创建Session,只访问HTML、IMAGE等静态资源并不会创建Session。如果尚未生成Session,也可以使用request.getSession(true)强制生成Session。

Session生成后,只要用户继续访问,服务器就会更新Session的最后访问时间,并维护该Session。用户每访问服务器一次,无论是否读写Session,服务器都认为该用户的Session“活跃(active)”了一次。

///session的有效期

由于会有越来越多的用户访问服务器,因此Session也会越来越多。为防止内存溢出,服务器会把长时间内没有活跃的Session从内存删除。这个时间就是Session的超时时间。如果超过了超时时间没访问过服务器,Session就自动失效了。

Session的超时时间为maxInactiveInterval属性,可以通过对应的getMaxInactiveInterval()获取,通过setMaxInactiveInterval(longinterval)修改。

 

Session的超时时间也可以在web.xml中修改。另外,通过调用Session的invalidate()方法可以使Session失效。

///session对浏览器的要求

虽然Session保存在服务器,对客户端是透明的,它的正常运行仍然需要客户端浏览器的支持。这是因为Session需要使用Cookie作为识别标志。HTTP协议是无状态的,Session不能依据HTTP连接来判断是否为同一客户,因此服务器向客户端浏览器发送一个名为JSESSIONID的Cookie,它的值为该Session的id(也就是HttpSession.getId()的返回值)。Session依据该Cookie来识别是否为同一用户。

该Cookie为服务器自动生成的,它的maxAge属性一般为–1,表示仅当前浏览器内有效,并且各浏览器窗口间不共享,关闭浏览器就会失效。

因此同一机器的两个浏览器窗口访问服务器时,会生成两个不同的Session。但是由浏览器窗口内的链接、脚本等打开的新窗口(也就是说不是双击桌面浏览器图标等打开的窗口)除外。这类子窗口会共享父窗口的Cookie,因此会共享一个Session。

注意:新开的浏览器窗口会生成新的Session,但子窗口除外。子窗口会共用父窗口的Session。例如,在链接上右击,在弹出的快捷菜单中选择“在新窗口中打开”时,子窗口便可以访问父窗口的Session。

 

如果客户端浏览器将Cookie功能禁用,或者不支持Cookie怎么办?例如,绝大多数的手机浏览器都不支持Cookie。Java Web提供了另一种解决方案:URL地址重写。【原理是将该用户Session的id信息重写到URL地址中。服务器能够解析重写后的URL获取Session的id。这样即使客户端不支持Cookie,也可以使用Session来记录用户状态】

///Session中禁止使用Cookie

既然WAP上大部分的客户浏览器都不支持Cookie,索性禁止Session使用Cookie,统一使用URL地址重写会更好一些。Java Web规范支持通过配置的方式禁用Cookie

转载地址:https://blog.csdn.net/fangaoxin/article/details/6952954/

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值