Cookie 与 Session

2019/03/01 cookiesession

在 Web 发展史中,我们知道浏览器与服务器间采用的是 http 协议,而这种协议是无状态的,所以这就导致了服务器无法知道是谁在浏览网页,但很明显,一些网页需要知道用户的状态,例如登陆,购物车等。

所以为了解决这一问题,先后出现了四种技术,分别是隐藏表单域URL重写cookiesession,而用的最多也是比较重要的就是 cookie 和 session 了。

# 是什么

Cookie 是浏览器保存在用户电脑上的一小段文本,通俗的来讲就是当一个用户通过 http 访问到服务器时,服务器会将一些 Key/Value 键值对返回给客户端浏览器,并给这些数据加上一些限制条件,在条件符合时这个用户下次访问服务器时,数据通过请求头又被完整地给带回服务器,服务器根据这些信息来判断不同的用户。

也就是说,Cookie 是服务器传给客户端并保存在客户端的一段信息,这个 Cookie 是有大小,数量限制的!!

可通过两种方式来创建 Cookie:

  1. 服务器通过发送一个 Set-Cookie 响应头部来创建 Cookie
    Set-Cookie: value[; expires=date][; domain=domain][; path=path][; secure]
    
  2. 浏览器通过 document.cookie 可以读写 Cookie

Cookie 的属性值包括:

属性 作用
name Cookie 名称
value 如果用于保存用户登录态,应该将该值加密,不能使用明文的用户标识
path 允许访问此 Cookie 的页面路径
domain 允许访问此 Cookie 的域名
expires/max-age 指定 Cookie 的生存期
http-only 不能通过 JS 访问 Cookie,减少 XSS 攻击
secure 只能在协议为 HTTPS 的请求中携带
same-site 规定浏览器不能在跨域请求中携带 Cookie,减少 CSRF 攻击

如果不设置 expires/max-age 这个 cookie 默认是 Session 的,也就是关闭浏览器该 cookie 就消失了

其中 sameSite 可以设置 3 类值:

  • Strict: 严格模式,完全禁止第三方 Cookie,跨站点时,任何情况下都不会发送 Cookie
  • Lax: 宽松模式,大多数情况不发送第三方 Cookie,但是导航到目标网址的 Get 请求除外
  • None: Chrome 计划将 Lax 变为默认设置。这时,网站可以选择显式关闭 SameSite 属性,将其设为 None。不过,前提是必须同时设置 Secure 属性(Cookie 只能通过 HTTPS 协议发送),否则无效

服务端通过 Set-Cookie 创建 Cookie 后,根据过期时间的不同,可区分为会话级别 Cookie持久级别 Cookie

  • 会话级别 Cookie:未指定过期时间,在浏览器关闭之后 Cookie 就会失效
  • 持久级别 Cookie:设置了过期时间,保存在硬盘的 Cookie,在过期时间之后失效

现在 Cookie 保存在了客户端,当我们去请求一个 URL 时,浏览器会根据这个 URL 路径,将符合条件的 Cookie 放在请求头中传给服务器。

# Session

Cookie 是有大小限制和数量限制的,并且越来越多的 Cookie 代表客户端和服务器的传输量增加,可不可以每次传的时候不传所有 Cookie 值,而只传一个唯一 ID,通过这个 ID 直接在服务器查找用户信息呢?答案是有的,这就是我们的 Session。

Session 是基于 Cookie 来工作的,同一个客户端每次访问服务器时,只要当浏览器在第一次访问服务器时,服务器设置一个 ID 并保存一些信息(例如登陆就保存用户信息,视具体情况),并把这个 ID 通过 Cookie 存到客户端,客户端每次和服务器交互时只传这个 ID,就可以实现维持浏览器和服务器的状态,而这个 ID 通常是 NAMEJSESSION 的一个 Cookie。

实际上,有四种方式让 Session 正常工作:

  1. 通过 URL 传递 SessionID
  2. 通过 Cookie 传递 SessionID
  3. 通过 SSL 传递 SessionID
  4. 通过隐藏表单传递 SessionID

第一种情况

当浏览器不支持 Cookie 功能时,浏览器会将用户的 SessionCookieName (默认为 JSESSIONID)重写到用户请求的 URL 参数中。格式:/path/Servlet;name=value;name2=value2?Name3=value3

第三种情况

会根据 javax.servlet.request.ssl_session 属性值设置 SessionID。

:如果客户端支持 Cookie,又通过 URL 重写,Tomcat 仍然会解析 Cookie 中的 SessionID 并覆盖 URL 中的 SessionID。

# 小结

# 二者的异同

相同点(有关系的地方)

  • Session 和 Cookie 都是为了让 http 协议有状态而存在
  • Session 通过 Cookie 工作,Cookie 传输的 SessionID 让 Session 知道这个客户端到底是谁

不同点

  • Session 将信息保存到服务器,Cookie 将信息保存在客户端

# 工作流程

当浏览器第一次访问服务器时,服务器创建 Session 并将 SessionID 通过 Cookie 带给浏览器保存在客户端,同时服务器根据业务逻辑保存相应的客户端信息保存在 session 中;客户端再访问时上传 Cookie,服务器得到 Cookie 后获取里面的 SessionID,来维持状态。

上次更新: 2022/6/21 10:24:01