从一开始迷糊到现在的session和cookie

news/2024/5/18 12:40:35 标签: session, cookie, rfc, servlet, tomcat源码

如果你说你不会sessioncookie,学java的人会对你嗤之以鼻,因为那是基础的技术,是面试中简单的问题,在网上有大量资料。但是,这并不是一个简单的问题。因为session这个词在被滥用,我读很多文档时都碰到过session,有时候人们说它是一次会话(会话又是什么?),有时说它是jsp的一个默认作用域,有时又说它是浏览器打开到关闭的一个情况……

关键的问题是,当我们在谈sessioncookie时,它指的是什么?

sessioncookie刨根问底

      • RFC2109
      • Cookie
      • JSESSIONID

RFC2109

This document describes a way to create stateful sessions with HTTP requests and responses. Currently, HTTP servers respond to each client request without relating that request to previous or
subsequent requests; the technique allows clients and servers that wish to exchange state information to place HTTP requests and responses within a larger context, which we term a “session”. This context might be used to create, for example, a “shopping cart”, in which user selections can be aggregated before purchase, or a magazine browsing system, in which a user’s previous reading affects which offerings are presented.

文档说的很清楚,为了解决http协议的无状态性,我们需要一种技术,这种技术能把http request和http response置于一种更大的上下文中,我们把它叫做session

There are, of course, many different potential contexts and thus many different potential types of session. The designers’ paradigm for sessions created by the exchange of cookies has these key attributes:

  1. Each session has a beginning and an end.
  2. Each session is relatively short-lived.
  3. Either the user agent or the origin server may terminate a session.
  4. The session is implicit in the exchange of state information.

由于上下文有很多种,因此session也有很多种。由cookie来实现的session有几个特点:

  • 每个session有开始有结束
  • 每个session相对短命
  • 客户端和服务端都能终结一个session
  • session在信息交换中是隐式存在的

The origin server initiates a session, if it so desires. (Note that “session” here does not refer to a persistent network connection but to a logical session created from HTTP requests and responses. The presence or absence of a persistent connection should have no effect on the use of cookie-derived sessions). To initiate a session, the origin server returns an extra response header to the client, Set-Cookie.

它说服务端初始化一个session,然后我们一直讲的session是一个逻辑概念,而大家平时讲的session是一种持续的客户端和服务端的网络连接。不管有没有这种连接,都不会影响cookie-derived的session的使用。

A user agent returns a Cookie request header (see below) to the origin server if it chooses to continue a session. The origin server may ignore it or use it to determine the current state of the session. It may send back to the client a Set-Cookie response heade with the same or different information, or it may send no Set-Cookie header at all. The origin server effectively ends a session by sending the client a Set-Cookie header with Max-Age=0.

origin server把cookie放在response header中,user agent回的cookie放在request header中。

语法和解析的细节我就不说了,大家可以自己去查阅文档。


它这里举了一个很好的例子:

    1.  User Agent -> Server

         POST /acme/login HTTP/1.1
         [form data]

         User identifies self via a form.

用户登录。


     2.  Server -> User Agent

         HTTP/1.1 200 OK
         Set-Cookie: Customer="WILE_E_COYOTE"; Version="1"; Path="/acme"

         Cookie reflects user's identity.

服务端把cookie放在header中。

    3.  User Agent -> Server

         POST /acme/pickitem HTTP/1.1
         Cookie: $Version="1"; Customer="WILE_E_COYOTE"; $Path="/acme"
         [form data]

         User selects an item for "shopping basket."

用户选了一件商品。user agent回的时候在VersionPath前都加了$,因为origin server在解析的时候会从左往右读,读到不是$开头的信息就找到了该cookiename(这里是Customer)。

 4.  Server -> User Agent

         HTTP/1.1 200 OK
         Set-Cookie: Part_Number="Rocket_Launcher_0001"; Version="1";
                 Path="/acme"

         Shopping basket contains an item.

购物车里放了商品。

   5.  User Agent -> Server

         POST /acme/shipping HTTP/1.1
         Cookie: $Version="1";
                 Customer="WILE_E_COYOTE"; $Path="/acme";
                 Part_Number="Rocket_Launcher_0001"; $Path="/acme"
         [form data]

         User selects shipping method from form.

用户选择支付手段。

6.  Server -> User Agent

         HTTP/1.1 200 OK
         Set-Cookie: Shipping="FedEx"; Version="1"; Path="/acme"

         New cookie reflects shipping method.

header中新添加的cookie反映了使用的支付手段。


     7.  User Agent -> Server

         POST /acme/process HTTP/1.1
         Cookie: $Version="1";
                 Customer="WILE_E_COYOTE"; $Path="/acme";
                 Part_Number="Rocket_Launcher_0001"; $Path="/acme";
                 Shipping="FedEx"; $Path="/acme"
         [form data]

         User chooses to process order.

用户选择处理订单。

    8.  Server -> User Agent

         HTTP/1.1 200 OK

         Transaction is complete.

成功,交易结束。

这个例子完美展示了如何通过cookie实现服务端和客户端的交流。


Cookie

上面的是规范,tomcat怎么实现的呢?

javax.servlet.http.Cookie的文档:

/**
 * Creates a cookie, a small amount of information sent by a servlet to a Web
 * browser, saved by the browser, and later sent back to the server. A cookie's
 * value can uniquely identify a client, so cookies are commonly used for
 * session management.
 * <p>
 * A cookie has a name, a single value, and optional attributes such as a
 * comment, path and domain qualifiers, a maximum age, and a version number.
 * Some Web browsers have bugs in how they handle the optional attributes, so
 * use them sparingly to improve the interoperability of your servlets.
 * <p>
 * The servlet sends cookies to the browser by using the
 * {@link HttpServletResponse#addCookie} method, which adds fields to HTTP
 * response headers to send cookies to the browser, one at a time. The browser
 * is expected to support 20 cookies for each Web server, 300 cookies total, and
 * may limit cookie size to 4 KB each.
 * <p>
 * The browser returns cookies to the servlet by adding fields to HTTP request
 * headers. Cookies can be retrieved from a request by using the
 * {@link HttpServletRequest#getCookies} method. Several cookies might have the
 * same name but different path attributes.
 * <p>
 * Cookies affect the caching of the Web pages that use them. HTTP 1.0 does not
 * cache pages that use cookies created with this class. This class does not
 * support the cache control defined with HTTP 1.1.
 * <p>
 * This class supports both the RFC 2109 and the RFC 6265 specifications.
 * By default, cookies are created using RFC 6265.
 */

因为cookie能够用来定位唯一确定的client,所以被用作session管理。

cookie既然能实现客户端和服务端的交流,那为什么要出现其他session技术呢?

因为cookie有缺点。

由于cookie暴露在了浏览器,所以不安全,而且容量小。


JSESSIONID

所以我们要用到HttpSession

public interface HttpSession
Provides a way to identify a user across more than one page request or visit to a Web site and to store information about that user.
The servlet container uses this interface to create a session between an HTTP client and an HTTP server. The session persists for a specified time period, across more than one connection or page request from the user. A session usually corresponds to one user, who may visit a site many times. The server can maintain a session in many ways such as using cookies or rewriting URLs.

This interface allows servlets to
1.View and manipulate information about a session, such as the session identifier, creation time, and last accessed time
2.Bind objects to sessions, allowing user information to persist across multiple user connections

HttpSession与用户一一对应。因此当一个用户登录JD之后,就不用在购物页面、支付页面重复登录了。

HttpSession在这方面与Cookie一模一样,它们都是session的具体实现。

至于关掉浏览器后,cookie是否还在,session是否还在,这个都可以自己写代码试一下。

现在的问题是,HttpSession怎么与一个client一一对应呢?

我们在HttpSession session = request.getSession();上打一个断点,观察浏览器第一次访问时的情况。


一直get。像getBean一样。


create。

这里的manager也是tomcat中的顶级管理接口。


创建session对象。

注意这里:

generateSessionId产生了sessionID,就是那一长串的32个字符的字符串。

服务端创建的session对象:


这个StandardSession就是HttpSessin的一个实现类。

服务端自己创建session之后,还要做一个工作:


他要在这个session的基础之上创建一个cookie


这个cookie的value就是sessionID的值。

那么这个特殊的cookie的key是多少呢?


那就是神秘的JSESSIONID

也就是说,当浏览器第一次访问服务器的时候,服务端会生成一个sessionID,然后以JSESSIONID作为key,以sessionID的值作为value创建一个cookie,然后添加到header中:


于是,浏览器的JSESSIONID的value就和服务端的sessionID对应了。

我们可以说,HttpSession是建立在Cookie之上的。


http://www.niftyadmin.cn/n/1312176.html

相关文章

hutool 读取扩展名文件_学会批量修改文件名,告别加班不是梦!

点击上方蓝字关注星标★不迷路本文作者&#xff1a;朱莉来源&#xff1a;Excel 小超人(ID&#xff1a;Julie1391)本文编辑&#xff1a;小叮PS&#xff1a;文末留言抽奖送秋叶家新书啦&#xff0c;记得看到最后&#xff01;说起批量修改文件名称&#xff0c;起初我是见 HR 的朋友…

五分钟教你屏蔽百度广告

简而言之&#xff1a;用插件&#xff0c;插件用js代码&#xff0c;js代码获取广告信息然后屏蔽 所需工具&#xff1a;浏览器和脚本管理器 下面列出常用的浏览器和对应的脚本管理器 Chrome&#xff1a;Tampermonkey或Violent monkey Firefox&#xff1a;Greasemonkey或Tampermon…

mybatis如何工作

如果自己能够写一个模仿mybatis工作的程序&#xff0c;那么看mybatis的源码就会很容易。 how mybatis works?pom配置文件与java类的映射加载配置文件执行sql并为实体类填充值sqlsessionTestpom <dependencies><dependency><groupId>dom4j</groupId>&l…

pands 画图 调整大小_关于数学建模的画图学习建议

数学建模&#xff0c;PPT&#xff0c;visio, matlab就够用了&#xff0c;其他根据特点备选。学会PPT里面的形状操作&#xff0c;搭建常用的示意图&#xff0c;还有调色等。matlab二维画图&#xff0c;三维画图会几个命令就行。其中二维画图用主要用plot&#xff08;包括好看的图…

oracle开发错误

先展示一个错误写法 public static String printGg_bysly0List() {// 外网TransManager tm new TransManager();try {// 获取要更改的人员String sql "select t.yrk057,t.aac002,t.yr0560 from gg_bysly0 t where t.yr0560 like 2018%";List<Gg_bysly0> syb…

Java如何加入皮肤_java皮肤包怎么才能使用

你的位置:问答吧-> JAVA-> 问题详情java皮肤包怎么才能使用在这里下了一个&#xff1a;http://download.csdn.net/source/760960不是jar文件&#xff0c;跟平常写的程序结构一样导入一个工程之后&#xff0c;出现很多包。。作者: junkli发布时间: 2010-08-06我晕死....什…

lc滤波电路电感电容值选择_π型滤波在开关电源的作用

常见的π型滤波是两个电容中间一个电感&#xff0c;有RC和LC两种类型&#xff0c;一般在输出电流不大的情况下用RC&#xff0c;并且R的取值不能太大&#xff0c;效果一般不如LC电路。在LC电路里有一个电感&#xff0c;可以根据输出电流大小和频率高低选择电感量的大小&#xff…

世纪前线网络质量测试工具 是什么_上海控安发布汽车信息安全评估工具箱:一款标准化、自动化的安全测试工具...

汽车网联化和智能化导致车载网络更为开放和复杂&#xff0c;面临着严峻的信息安全风险和挑战&#xff0c;汽车安全测试工作备受重视。安全测试行业现状及痛点&#xff1a;• 工程师主要通过人为分析进行测试建模&#xff0c;对整车或零部件进行信息安全测试&#xff0c;极大依赖…