在通常的使用中,我们只知道session信息是存放在服务器端,而cookie是存放在客户端。但服务器如何使用session和客户端之间进行通信,以及jsessionId是怎么回事,这并没有一个完整和正确的认识,因此这里将这类信息汇总。

session中的jsessionId是在session创建好之后,发送给客户端。然后在每一次请求中,客户端即会将这个信息传递给服务器端,服务器端使用这个信息来维护和客户端之间的会话通信,在浏览器关闭之后,这个session就消失了。

而对于普通的cookie来说,它是有着一定的时间存放在客户端的机器中的。当下次打开浏览器时,这个cookie就会被读取,同时在请求时发放到服务器端。在关闭浏览器,这个cookie仍然存在的,并没有消失。

那么,这两者之间有没有联系呢,这就要看官方对于Cookie的不同分类,其实就对应着session Cookie和psersistent Cookie的描述了。如下所示:

Session Cookie

A user’s session
cookie[15] (also known as an in-memory cookie or transient cookie) for a
website exists in temporary memory only while the user is reading and
navigating the website. When an expiry date or validity interval is not
set at cookie creation time, a session cookie is created. Web browsers
normally delete session cookies when the user closes the browser.

Persistent cookie

A persistent
cookie[15] will outlast user sessions. If a persistent cookie has its
Max-Age set to 1 year (for example), then, during that year, the initial
value set in that cookie would be sent back to the server every time
the user visited the server. This could be used to record a vital piece
of information such as how the user initially came to this website. For
this reason, persistent cookies are also called tracking cookies.

从上面的描述中看,所谓的
session
Cookie,就是我们所说的session,其实就是一个没有设置过期时间的cookie信息。而普通的cookie,即我们通常所说的cookie,
就是设置了过期时间(有效时间,通常大于一个特定的值,如一周)的cookie。

那么,我们可以这样认为。
session就是服务器端,通过使用session
Cookie来维系客户端和服务器的关系,而所谓的存储就是在服务器端针对这个session值(如jsessionId值)作了一个内部的增强,可以围
绕着这个session
Cookie创建一个单独的数据存储器(如map),然后来实现我们所谓的session数据存储呢。既然这样,在一些特定的场景(如分布式环境),是否
可以按照这种设计思路设计另外的session存储呢,这也是可以的。

接下来,我们可测试一下这种思路,是否正确。有两个很简单的servlet,一个为写cookie,另一个为读cookie。如下所示:

Java
//writeServlet
//add memory cookie
        Cookie cookie = new Cookie("memoryCookie", "12345678");
        cookie.setMaxAge(-1);
        resp.addCookie(cookie);

//add normal cookie
        cookie = new Cookie("persistentCookie", "abcdefg");
        cookie.setMaxAge(300);//one minute
        resp.addCookie(cookie);

//readServlet
Cookie[] cookies = req.getCookies();
        for(Cookie cookie : cookies) {
            System.out.println(
                    cookie.getPath() + "->" + cookie.getName() + "->" + cookie.getValue() + "->" + cookie.getMaxAge());
        }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//writeServlet
//add memory cookie
        Cookie cookie=newCookie("memoryCookie","12345678");
        cookie.setMaxAge(-1);
        resp.addCookie(cookie);
 
        //add normal cookie
        cookie=newCookie("persistentCookie","abcdefg");
        cookie.setMaxAge(300);//one minute
        resp.addCookie(cookie);
 
//readServlet
Cookie[]cookies=req.getCookies();
        for(Cookie cookie:cookies){
            System.out.println(
                    cookie.getPath()+"->"+cookie.getName()+"->"+cookie.getValue()+"->"+cookie.getMaxAge());
        }

1    未访问write,直接访问read时

开启F12,查看浏览器端的请求信息,如下所示:

只上传了一个jsession信息(这里是因为我修改了sessionName的原因)。

而在后台,打印结果如下所示:

Java
null->tomcat7utf8_session->F5B543F5D5FD4A9B78CA18D96D4CE995->-1
1
null->tomcat7utf8_session->F5B543F5D5FD4A9B78CA18D96D4CE995->-1

即只有jsessionId信息。

2    访问write,再访问read

开启F12,我们查看一下访问write之后 的cookie情况,如下所示:

以上图为响应头信息。

可以看出,在响应返回时,服务器返回了2个cookie,而key为memoryCookie的信息并没有过期信息.

那我们再访问一下write,相应信息如下所示.

这是请求头信息:

而相应的cookie信息也同样如下所示:

在后台,打印的cookie信息如下所示:

JavaScript
null->tomcat7utf8_session->F5B543F5D5FD4A9B78CA18D96D4CE995->-1
null->memoryCookie->12345678->-1
null->persistentCookie->abcdefg->-1
1
2
3
null->tomcat7utf8_session->F5B543F5D5FD4A9B78CA18D96D4CE995->-1
null->memoryCookie->12345678->-1
null->persistentCookie->abcdefg->-1

这里显示的maxAge是-1,这是因为客户端本身就没传递相应的maxAge,所以未获取到。并且这个信息从获取来说,并没有实际性的意义。

3 关闭浏览器,再访问read

我们关闭一次浏览器,再看一下相应的数据信息,如下所示:

后台打印信息如下:

null->persistentCookie->abcdefg->-1

null->tomcat7utf8_session->6B6E27A4F6B71853CC2D2C58BEE83238->-1

即可以看出,在重新打开浏览器(并且之前写的persistentCookie并没有过期)时,在请求后台读取时,只会发送有效的信息。而之前的内存cookie已随着浏览器关闭消失了,所以这里才只会有2个信息。

需要注意的,这里的关闭浏览器,是把所有的标签界面均关闭。在IE中,标签而中是共享Cookie的,所以只关闭一个标签是没有作用的。

4 如何创建的Session

这里,我们来查看一下在后台是如何创建session,并同时产生相应的
cookie信息的。我们可以这样认为,当我们请求后台session时,如果没有相应的cookie信息,后台会产生一个相应的cookie,并发到客
户端(即调用response.addCookie方法)。来看一下后台的实现是否如我们所说呢(这里以tomcat实现为参考),相应的代码在类
Request.doGetSession中,如下所示:

Java
    protected Session doGetSession(boolean create) {
。。。。。。

//这里尝试获取session或者创建一个新的session
        // Attempt to reuse session id if one was submitted in a cookie
        // Do not reuse the session id if it is from a URL, to prevent possible
        // phishing attacks
        if (connector.getEmptySessionPath()
                && isRequestedSessionIdFromCookie()) {
//这里如果客户端显示传递了一个sessionId,这里直接从session池中获取,如果获取失败则直接返回null,被认为是客户端数据有问题或者是其它攻击
            session = manager.createSession(getRequestedSessionId());
        } else {
            session = manager.createSession(null);
        }

//这里就是创建一个新的cookie,并放置在response头中
        // Creating a new session cookie based on that session
        if ((session != null) && (getContext() != null)
               && getContext().getCookies()) {
            String scName = context.getSessionCookieName();
            if (scName == null) {
                scName = Globals.SESSION_COOKIE_NAME;
            }
//name即jsessionId或配置的sessionName value即我们所说的sessionId
            Cookie cookie = new Cookie(scName, session.getIdInternal());
            configureSessionCookie(cookie);
            response.addSessionCookieInternal(cookie, context.getUseHttpOnly());
        }
。。。。。。
    }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
    protectedSession doGetSession(booleancreate){
。。。。。。
 
//这里尝试获取session或者创建一个新的session
        // Attempt to reuse session id if one was submitted in a cookie
        // Do not reuse the session id if it is from a URL, to prevent possible
        // phishing attacks
        if(connector.getEmptySessionPath()
                &&isRequestedSessionIdFromCookie()){
//这里如果客户端显示传递了一个sessionId,这里直接从session池中获取,如果获取失败则直接返回null,被认为是客户端数据有问题或者是其它攻击
            session=manager.createSession(getRequestedSessionId());
        }else{
            session=manager.createSession(null);
        }
 
        //这里就是创建一个新的cookie,并放置在response头中
        // Creating a new session cookie based on that session
        if((session!=null)&&(getContext()!=null)
               &&getContext().getCookies()){
            StringscName=context.getSessionCookieName();
            if(scName==null){
                scName=Globals.SESSION_COOKIE_NAME;
            }
//name即jsessionId或配置的sessionName value即我们所说的sessionId
            Cookie cookie=newCookie(scName,session.getIdInternal());
            configureSessionCookie(cookie);
            response.addSessionCookieInternal(cookie,context.getUseHttpOnly());
        }
。。。。。。
    }

可以看出,这和我们的大致思路是一样的。

5 Cookie中的HttpOnly

The HttpOnly attribute is supported by most modern browsers.[19][20] On a supported browser, an HttpOnly session cookie will be used only when transmitting HTTP (or HTTPS) requests, thus restricting access from other, non-HTTP APIs (such as JavaScript). This restriction mitigates but does not eliminate the threat of session cookie theft via cross-site scripting (XSS).[21] This feature applies only to session-management cookies, and not other browser cookies.

现在的浏览器已经支持在cookie中增加一个新的httpOnly选项,这个选项就表示这个cookie只用于在浏览器请求中使用,而不能被其它方式读取和设置。比如,httpOnly式的cookie就不能被js读取到(而常规的cookie是可以读取的)。

在最新的J2EE6.0即Servlet3.0中,已经支持直接在Cookie上设置httpOnly选项了。而在之间的版本,如tomcat,则 可以在context.xml中设置是否支持httpOnly选项。针对像session Cookie这种会话式cookie,建议是使用httpOnly的,并且默认也是直接使用此标记的。

ps:http://www.iflym.com/index.php/code/201402170002.html

会话Cookie与session的关系的更多相关文章

  1. 会话Cookie及session的关系(Cookie & Session)

    会话Cookie及session的关系(Cookie & Session) 在通常的使用中,我们只知道session信息是存放在服务器端,而cookie是存放在客户端.但服务器如何使用sess ...

  2. 程序员过关斩将--cookie和session的关系其实很简单

    月高风下,下班路上.... 菜菜哥,告诉你一个秘密,但是不允许告诉任何人 这么秘密,你有男票了?~ 不是,昨天我偷偷去面试了,结果挂了 这不是好事吗,上天让公司留住你..... 好吧,不过还是要请教你 ...

  3. cookie和session的关系和区别

    1.为什么会用到cookie和session 由于http请求是一种无状态的请求,一旦数据交换完毕便会关闭请求,再次交换数据则要再次发起请求,所以服务端无法通过连接追踪会话,确定用户身份,而cooki ...

  4. (进阶篇)浅谈COOKIE和SESSION关系和区别

    COOKIE介绍 cookie 常用于识别用户.cookie 是服务器留在用户计算机中的小文件.每当相同的计算机通过浏览器请求页面时,它同时会发送 cookie.通过 PHP,您能够创建并取回 coo ...

  5. 转:理解Cookie和Session机制

    原文: 理解Cookie和Session机制 摘要: Cookie工作原理 由于HTTP是一种无状态的协议,服务器单从网络连接上无从知道客户身份.怎么办呢?就给客户端们颁发一个通行证吧,每人一个,无论 ...

  6. cookie和session详解[转]

    文章链接: http://aijezdm915.iteye.com/blog/1272530 cookie.session 都是用来保存用户状态信息的一种方法或手段 二者主要区别是:         ...

  7. cookie和session(一)

    先来谈谈我对session和cookie的理解,事实上,只要你去面试web开发,面试官十有八九会问这个问题. cookie和session经常被放在一起问,其实在我看来这两个东西完全是两个不一样的. ...

  8. 二、Django用户认证之cookie和session

    1.cookie原理 Cookie意为“甜饼”,是由W3C组织提出,最早由Netscape社区发展的一种机制.目前Cookie已经成为标准,所有的主流浏览器如IE.Netscape.Firefox.O ...

  9. http 之cookie和session

     cookie和session 关于http: 1.http是:无状态.短连接 2.http的请求生命周期:给服务端发送一个请起头,通过域名提取url,通过路由关系匹配,再通过函数+html进行模板加 ...

随机推荐

  1. 数据库建表权限 CREATE command denied to user for table

    今天在表中用Navicat连接服务器上的mysql账号进行建表,报了个这样类似的错, CREATE command denied to user for table 是数据库权限设置的问题,所以无法进 ...

  2. CI/CD-企业级DevOps

    CI/CD-企业级DevOps 什么是DevOps? DevOps是一种思想或方法论,它涵盖开发.测试.运维的整个过程! DevOps强调软件开发人员与软件测试.软件运维.质量保障(QA) 部门之间有 ...

  3. CF1082G Petya and Graph(最小割,最大权闭合子图)

    QWQ嘤嘤嘤 感觉是最水的一道\(G\)题了 顺便记录一下第一次在考场上做出来G qwqqq 题目大意就是说: 给你n个点,m条边,让你选出来一些边,最大化边权减点权 \(n\le 1000\) QW ...

  4. seata整合多数据源

    seata整合多数据源 一.背景 二.整合步骤 1.seata server的搭建 2.引入数据源切换组件 3.引入seata组件 4.配置多数据源 5.关闭seata自己默认的数据源代理 6.配置s ...

  5. DP接口中AUX

    背景技术: DP接口(DisplayPort)是一种图像显示接口,它不仅可以支持全高清显示分辨率(1920×1080),还能支持4k分辨率(3840×2160),以及最新的8k分辨率(7680×432 ...

  6. 零基础如何更好的学习Linux

    本节旨在介绍对于初学者如何学习 Linux 的建议.如果你已经确定对 Linux 产生了兴趣,那么接下来我们介绍一下学习 Linux 的方法. 如何去学习 学习大多类似庖丁解牛,对事物的认识一般都是由 ...

  7. 单片机stm32的5个时钟源的详细分析

    众所周知STM32有5个时钟源HSI.HSE.LSI.LSE.PLL,其实他只有四个,因为从上图中可以看到PLL都是由HSI或HSE提供的. 其中,高速时钟(HSE和HSI)提供给芯片主体的主时钟.低 ...

  8. shell脚本自学笔记

    一. 什么是Shell脚本 shell脚本并不能作为正式的编程语言,因为它是在linux的shell中运行的,所以称为shell脚本.事实上,shell脚本就是一些命令的集合. 假如完成某个需求需要一 ...

  9. 好的编程习惯是减少bug最有效的方法

    公司来了几个新手,有时候很简单的一个功能模块都要耗费好几天时间,总是在一些不相关的问题上死耗一整天,搞出莫名其妙的问题,找不到具体原因,总是怀疑编译出问题了,系统出问题了,板子出问题了,搞到快下班了叫 ...

  10. word-break-ii leetcode C++

    Given a string s and a dictionary of words dict, add spaces in s to construct a sentence where each ...