session 和 cookie
网络早期最大的问题之一是如何管理状态。简而言之就是服务器无法知道两个请求是否来自同一个浏览器。
会话跟踪是Web
程序中常用的技术,用来跟踪用户的整个会话。常用的会话跟踪技术是Cookie
与Session
。Cookie
通过在客户端记录信息确定用户身份,Session
通过在服务器端记录信息确定用户身份。
Cookie
原理
由于 http
是无状态的协议,一旦客户端和服务器的数据交换完毕,就会断开连接,再次请求,会重新连接,这就说明服务器单从网络连接上是没有办法知道用户身份的。为了解决这个问题,就给每次新的用户请求时,发一个身份证,每次访问都要带上身份证,这样服务器就知道是谁来访问了,针对不同的用户做出不同的响应。
类型
按照过期时间分为两类:
- 会话
Cookie
:是一种临时cookie
,用户退出浏览器,就会被删除 - 持久
Cookie
:存放在硬盘中,关闭浏览器或者重启电脑依然存在,保留时间由设置的有效期或者过期时间决定,通常是维护某个用户周期性访问服务器的配置文件或者登陆信息
不可跨域名性
Cookie
具有不可跨域名性。根据Cookie
规范,浏览器访问Google
只会携带Google
的Cookie
,而不会携带Baidu
的Cookie
。Google
也只能操作Google
的Cookie
,而不能操作Baidu
的Cookie
。
属性
- 域:服务器可以向
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.com
和 m.zhaunzhuan.58.com/user/
这两个url
。 m.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
:设置了属性secure
,cookie
只有在https
协议加密情况下才会发送给服务端。但是这并不是最安全的,由于其固有的不安全性,敏感信息也是不应该通过cookie
传输的(chrome 52
和firefox 52
开始不安全的(HTTP
)是无法使用secure
的)
操作 cookie
通过docuemnt.cookie
可以设置和获取Cookie
的值
document.cookie = "user=wang";
console.log(document.cookie);
禁止javascript
操作cookie
(为避免跨域脚本(xss
)攻击,通过javascript
的document.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
例如购物车