session 和 cookie

1,755 阅读4分钟

session 和 cookie

网络早期最大的问题之一是如何管理状态。简而言之就是服务器无法知道两个请求是否来自同一个浏览器。

会话跟踪是Web程序中常用的技术,用来跟踪用户的整个会话。常用的会话跟踪技术是CookieSessionCookie通过在客户端记录信息确定用户身份,Session通过在服务器端记录信息确定用户身份。

Cookie

原理

由于 http 是无状态的协议,一旦客户端和服务器的数据交换完毕,就会断开连接,再次请求,会重新连接,这就说明服务器单从网络连接上是没有办法知道用户身份的。为了解决这个问题,就给每次新的用户请求时,发一个身份证,每次访问都要带上身份证,这样服务器就知道是谁来访问了,针对不同的用户做出不同的响应。

类型

按照过期时间分为两类:

  • 会话 Cookie:是一种临时 cookie ,用户退出浏览器,就会被删除
  • 持久 Cookie:存放在硬盘中,关闭浏览器或者重启电脑依然存在,保留时间由设置的有效期或者过期时间决定,通常是维护某个用户周期性访问服务器的配置文件或者登陆信息

不可跨域名性

Cookie具有不可跨域名性。根据Cookie规范,浏览器访问Google只会携带GoogleCookie,而不会携带BaiduCookieGoogle也只能操作GoogleCookie,而不能操作BaiduCookie

属性

  • 域:服务器可以向 set-cookie 响应首部添加一个 Domain 属性来控制哪些站点可以看到 cookie
Set-Cookie: name="wang"; domain="m.zhuanzhuan.58.com"

如果用户访问的是 m.zhuanzhuan.58.com 那就会发送 cookie: name="wang", 如果用户访问www.aaa.com(非 zhuanzhuan.58.com)就不会发送这个 Cookie

  • 路径:可以为服务器特定文档指定 Cookie,这个属性设置的 url 且带有这个前缀的 url 路径都是有效的。

例如:m.zhuanzhuan.58.comm.zhaunzhuan.58.com/user/这两个urlm.zhuanzhuan.58.com 设置cookie

Set-cookie: id="123432";domain="m.zhuanzhuan.58.com";

m.zhaunzhuan.58.com/user/ 设置cookie

Set-cookie:user="wang", domain="m.zhuanzhuan.58.com"; path=/user/

但是访问其他路径m.zhuanzhuan.58.com/other/就会获得

cookie: id="123432"

如果访问m.zhuanzhuan.58.com/user/就会获得

  cookie: id="123432"
  cookie: user="wang"
  • secure:设置了属性securecookie只有在https协议加密情况下才会发送给服务端。但是这并不是最安全的,由于其固有的不安全性,敏感信息也是不应该通过cookie传输的(chrome 52firefox 52 开始不安全的(HTTP)是无法使用secure的)

操作 cookie

通过docuemnt.cookie可以设置和获取Cookie的值

document.cookie = "user=wang";
console.log(document.cookie);

禁止javascript操作cookie(为避免跨域脚本(xss)攻击,通过javascriptdocument.cookie无法访问带有HttpOnly标记的cookie

Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2017 07:28:00 GMT; Secure; HttpOnly

第三方 cookie

通常cookie的域和浏览器地址的域匹配,这被称为第一方cookie。那么第三方cookie就是cookie的域和地址栏中的域不匹配,这种cookie通常被用在第三方广告网站。为了跟踪用户的浏览记录,并且根据收集的用户的浏览习惯,给用户推送相关的广告。


Session

Cookie机制弥补了HTTP协议无状态的不足。在Session出现之前,基本上所有的网站都采用Cookie来跟踪会话。

Cookie不同的是,session是以服务端保存状态的。

原理

当客户端请求创建一个session的时候,服务器会先检查这个客户端的请求里是否已包含了一个session标识 - sessionId

  • 如果已包含这个sessionId,则说明以前已经为此客户端创建过session,服务器就按照sessionId把这个session检索出来使用(如果检索不到,可能会新建一个)
  • 如果客户端请求不包含sessionId,则为此客户端创建一个session并且生成一个与此session相关联的sessionId

sessionId的值一般是一个既不会重复,又不容易被仿造的字符串,这个sessionId将被在本次响应中返回给客户端保存。保存sessionId的方式大多情况下用的是cookie

有效期

session一般在内存中存放,内存空间本身大小就有一定的局限性,因此session需要采用一种过期删除的机制来确保session信息不会一直累积,来防止内存溢出的发生。

session的超时时间可以通过maxInactiveInterval属性来设置。

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

  • 通过URL传递SessionID
  • 通过Cookie传递SessionID
  • 通过SSL传递SessionID
  • 通过隐藏表单传递SessionID

区别和联系

差异 cookie session
存储位置 客户端 服务器
数据类型 字符串 对象
访问权限 设置路径则某些地方不能访问 同一用户所有都可以访问

相同:

  • 都是为了解决 hhttp 无状态的问题
  • 都是基于 cookie

应用场景

  • 重要状态使用 session ,例如用户登录信息
  • 不重要的使用 cookie 例如购物车