cookie_Session
Take my wine in my own cup, friend.
It loses its wreath of foam when poured into that of others.
在我自己的杯中,饮了我的酒吧,朋友。
一倒在别人的杯里,这酒的腾跳的泡沫便要消失了。
会话(Session)跟踪是Web程序中常用的技术,用来跟踪用户的整个会话。常用的会话跟踪技术是Cookie与Session。Cookie通过在客户端记录信息确定用户身份,Session通过在服务器端记录信息确定用户身份。
Cookie
客户端技术
Cookie意为“甜饼”,是由W3C组织提出,最早由Netscape社区发展的一种机制。目前Cookie已经成为标准,所有的主流浏览器如IE、Netscape、Firefox、Opera等都支持Cookie。
由于HTTP是一种无状态的协议,服务器单从网络连接上无从知道客户身份。怎么办呢?就给客户端们颁发一个通行证吧,每人一个,无论谁访问都必须携带自己通行证。这样服务器就能从通行证上确认客户身份了。这就是Cookie的工作原理。
Java中把Cookie封装成了javax.servlet.http.Cookie
类。每个Cookie都是该Cookie类的对象。服务器通过操作Cookie类对象对客户端Cookie进行操作。通过request.getCookie()获取客户端提交的所有Cookie(以Cookie[]数组形式返回),通过response.addCookie(Cookiecookie)向客户端设置Cookie。
Cookie实际上是一小段的文本信息。客户端请求服务器,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个Cookie。客户端浏览器会把Cookie保存起来。当浏览器再请求该网站时,浏览器把请求的网址连同该Cookie一同提交给服务器。服务器检查该Cookie,以此来辨认用户状态。服务器还可以根据需要修改Cookie的内容。
创建
创建一个 Cookie 对象:可以调用带有 cookie 名称和 cookie 值的 Cookie 构造函数,cookie 名称和 cookie 值都是字符串。
1
Cookie cookie = new Cookie("key","value");
设置最大生存周期:可以使用 setMaxAge 方法来指定 cookie 能够保持有效的时间(以秒为单位)。
1
cookie.setMaxAge(60*60*24);
发送 Cookie 到 HTTP 响应头:可以使用 response.addCookie 来添加 HTTP 响应头中的 Cookie.
1
response.addCookie(cookie);
方法 | 描述 |
---|---|
public void setDomain(String pattern) | 该方法设置 cookie 适用的域 |
public String getDomain() | 该方法获取 cookie 适用的域 |
public void setMaxAge(int expiry) | 该方法设置 cookie 过期的时间(以秒为单位)。如果不这样设置,cookie 只会在当前 session 会话中持续有效。 |
public int getMaxAge() | 该方法返回 cookie 的最大生存周期(以秒为单位),默认情况下,-1 表示 cookie 将持续下去,直到浏览器关闭。 |
public String getName() | 该方法返回 cookie 的名称。名称在创建后不能改变。 |
public void setValue(String newValue) | 该方法设置与 cookie 关联的值。 |
public String getValue() | 该方法获取与 cookie 关联的值。 |
public void setPath(String uri) | 该方法设置 cookie 适用的路径。如果您不指定路径,与当前页面相同目录下的(包括子目录下的)所有 URL 都会返回 cookie。 |
public String getPath() | 该方法获取 cookie 适用的路径。 |
public void setSecure(boolean flag) | 该方法设置布尔值,表示 cookie 是否应该只在加密的(即 SSL)连接上发送。 |
public void setComment(String purpose) | 设置cookie的注释。该注释在浏览器向用户呈现 cookie 时非常有用。 |
public String getComment() | 获取 cookie 的注释,如果 cookie 没有注释则返回 null。 |
实例
保存用户上一次访问的时间
1 |
|
- Cookie功能需要浏览器的支持
删除Cookie
1 |
|
中文传递数据
1 |
|
cookie的安全属性
HTTP协议不仅是无状态的,而且是不安全的。使用HTTP协议的数据不经过任何加密就直接在网络上传播,有被截获的可能。使用HTTP协议传输很机密的内容是一种隐患。如果不希望Cookie在HTTP等非安全协议中传输,可以设置Cookie的secure属性为true。浏览器只会在HTTPS和SSL等安全协议中传输此类Cookie。下面的代码设置secure属性为true:
1 |
|
提示:secure属性并不能对Cookie内容加密,因而不能保证绝对的安全性。如果需要高安全性,需要在程序中对Cookie内容加密、解密,以防泄密
Session
服务器技术
Session是服务器端使用的一种记录客户端状态的机制
Session是另一种记录客户状态的机制,不同的是Cookie保存在客户端浏览器中,而Session保存在服务器上。客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上。这就是Session。客户端浏览器再次访问时只需要从该Session中查找该客户的状态就可以了。
Session对应的类为javax.servlet.http.HttpSession
类。每个来访者对应一个Session对象,所有该客户的状态信息都保存在这个Session对象里。Session对象是在客户端第一次请求服务器的时候创建的。Session也是一种key-value的属性对,通过getAttribute(Stringkey)
和setAttribute(String key,Objectvalue)
方法读写客户状态信息。Servlet里通过request.getSession()
方法获取该客户的Session。
方法 | 描述 |
---|---|
public Object getAttribute(String name) | 该方法返回在该 session 会话中具有指定名称的对象,如果没有指定名称的对象,则返回 null。 |
public Enumeration getAttributeNames() | 该方法返回 String 对象的枚举,String 对象包含所有绑定到该 session 会话的对象的名称。 |
public long getCreationTime() | 该方法返回该 session 会话被创建的时间,自格林尼治标准时间 1970 年 1 月 1 日午夜算起,以毫秒为单位。 |
public String getId() | 该方法返回一个包含分配给该 session 会话的唯一标识符的字符串。 |
public long getLastAccessedTime() | 该方法返回客户端最后一次发送与该 session 会话相关的请求的时间自格林尼治标准时间 1970 年 1 月 1 日午夜算起,以毫秒为单位。 |
public int getMaxInactiveInterval() | 该方法返回 Servlet 容器在客户端访问时保持 session 会话打开的最大时间间隔,以秒为单位。 |
public void invalidate() | 该方法指示该 session 会话无效,并解除绑定到它上面的任何对象。 |
public boolean isNew() | 如果客户端还不知道该 session 会话,或者如果客户选择不参入该 session 会话,则该方法返回 true。 |
public void removeAttribute(String name) | 该方法将从该 session 会话移除指定名称的对象。 |
public void setAttribute(String name, Object value) | 该方法使用指定的名称绑定一个对象到该 session 会话。 |
public void setMaxInactiveInterval(int interval) | 该方法在 Servlet 容器指示该 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
1 |
|
- request还可以使用getSession(boolean create)来获取Session。区别是如果该客户的Session不存在,request.getSession()方法会返回null,而getSession(true)会先创建Session再将Session返回。
移除Session
1 |
|
- 设置 session 会话过期时间:可以调用
public void setMaxInactiveInterval(int interval)
方法来单独设置 session 会话超时。
在web.xml中设置Session默认失效时间
1 |
|
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地址重写。
URL 重写
可以在每个 URL 末尾追加一些额外的数据来标识 session 会话,服务器会把该 session 会话标识符与已存储的有关 session 会话的数据相关联。URL地址重写的原理是将该用户Session的id信息重写到URL地址中。
URL 重写是一种更好的维持 session 会话的方式,它在浏览器不支持 cookie 时能够很好地工作,但是它的缺点是会动态生成每个 URL 来为页面分配一个 session 会话 ID,即使是在很简单的静态 HTML 页面中也会如此。
HttpServletResponse
类提供了encodeURL(Stringurl)
实现URL地址重写
1 |
|
该方法会自动判断客户端是否支持Cookie。如果客户端支持Cookie,会将URL原封不动地输出来。如果客户端不支持Cookie,则会将用户Session的id重写到URL中。
重写后的输出可能是这样的:
1 |
|
如果是页面重定向(Redirection),URL地址重写可以这样写:
1 |
|
效果跟response.encodeURL(String url)
是一样的:如果客户端支持Cookie,生成原URL地址,如果不支持Cookie,传回重写后的带有jsessionid字符串的地址。
注意:TOMCAT判断客户端浏览器是否支持Cookie的依据是请求中是否含有Cookie。尽管客户端可能会支持Cookie,但是由于第一次请求时不会携带任何Cookie(因为并无任何Cookie可以携带),URL地址重写后的地址中仍然会带有jsessionid。当第二次访问时服务器已经在浏览器中写入Cookie了,因此URL地址重写后的地址中就不会带有jsessionid了。
cookie和session的区别
cookie数据存放在客户的浏览器上,session数据放在服务器上
Cookie是把用户的数据写给用户的浏览器,浏览器保存(可以保存多个);
Session是把用户的数据写到用户独占的Session中,服务器保存(保存重要的信息,减少服务器资源的浪费);
简单的说,当你登录一个网站的时候,如果web服务器端使用的是session,那么所有的数据都保存在服务器上面,客户端每次请求服务器的时候会发送 当前会话的session_id,服务器根据当前session_id判断相应的用户数据标志,以确定用户是否登录,或具有某种权限。
由于数据是存储在服务器 上面,所以你不能伪造,但是如果你能够获取某个登录用户的session_id,用特殊的浏览器伪造该用户的请求也是能够成功的。
session_id是服务器和客户端链接时候随机分配的,一般来说是不会有重复,但如果有大量的并发请求,也不是没有重复的可能性。
Session是由应用服务器维持的一个服务器端的存储空间,用户在连接服务器时,会由服务器生成一个唯一的SessionID,用该SessionID 为标识符来存取服务器端的Session存储空间。而SessionID这一数据则是保存到客户端,用Cookie保存的,用户提交页面时,会将这一 SessionID提交到服务器端,来存取Session数据。这一过程,是不用开发人员干预的。所以一旦客户端禁用Cookie,那么Session也会失效。
cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗考虑到安全应当使用session;
- 设置cookie时间可以使cookie过期。但是使用session-destory(),我们将会销毁会话;
- session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能考虑到减轻服务器性能方面,应当使用cookie;
- 单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。(Session对象没有对存储的数据量的限制,其中可以保存更为复杂的数据类型);
注意:
- session很容易失效,用户体验很差;
- 虽然cookie不安全,但是可以加密 ;
- cookie也分为永久和暂时存在的;
- 浏览器 有禁止cookie功能 ,但一般用户都不会设置;
- 一定要设置失效时间,要不然浏览器关闭就消失了;
两者最大的区别在于生存周期,一个是浏览器启动到浏览器关闭.(浏览器页面一关 ,session就消失了),一个是预先设置的生存周期,或永久的保存于本地的文件。(cookie)
- 本文作者:bobo
- 本文链接:https://boyolo.github.io/article/32177.html
- 版权声明:本博客所有文章均采用 BY-NC-SA 许可协议,转载请注明出处!