乐趣区

Cookie和Session

cookie

1. 是什么?

服务器保存在浏览器的一小段文本信息,≤4kB
不同浏览器或不同网站 cookie 都不同,相同网站不同浏览器的 cookie 键相同,值不同,键值顺序不同

问:SRCHD=AF=NOFORM; 这个 cookie 的键值对是什么
答:字符串中第一个 = 作为键值对的分隔符,所以该 cookie 的健为 SRCHD,值为 AF=NOFORM,如下图:

2. 功能?

HTTP 无状态
服务器用来分辨两个请求是否来自同一浏览器,保存一些状态信息
对话管理:登录、购物车等对话管理
个性化:网页字体大小、背景色等用户偏好
追踪:记录和分析用户行为

3. 如何设置?

每个 cookie 键值对都可以设置 Expires、Max-Age、Path、Domain、Secure、HttpOnly 等属性
Expire、Max-Age(秒):同时存在 Max-Age 优先级更高,都没有设置就是 session cookie
Domain、Path:域名、HTTP 请求路径 /…
Secure:只应通过 HTTPS 协议加密过的请求发送给服务器(不保证绝对安全),http 协议自动关,https 协议自动开
HttpOnly:无法通过 document.cookie 访问,只能发送给服务端

Cookie 创建:

游览器端和服务端都可以创建 cookie:

  1. 游览器端可以用 js 的 document.cookie="key=value"; 来设置
  2. 服务器端可以使用对应语言的 cookie 操作函数(如 php 的 setcookie),然后在服务端返回给客户端的 HTTP Response 头部会带上 Set-Cookie,游览器拿到这个 cookie 后会在以后的请求头中带上这个 cookie,下面是一个服务器端返回头里的 Set-Cookie 例子:
Set-Cookie: id=a3fWa; expires=Wed, 21 Oct 2015 07:28:00 GMT;secure; httpOnly=true; domain=bing.com; path=/;

流程:浏览器首次访问服务器 >>> 服务器在响应头中写入 cookie,返回给浏览器 >>> 浏览器携带 cookie 再次访问服务器 >>> 服务器根据 cookie 判断请求来自同一浏览器

Cookie 更改:

重新调用各端的 cookie 设置函数复写原来的 key 即可,这里需要注意,修改时需要 name、domain、path、secure 属性和原来的属性玩阿暖匹配才会修改原来的那一条值,否则会生成一条同名的新 cookie

Cookie 删除:

重新调用各端的 cookie 设置函数,将要删除的 cookie 的 expire 属性设置为一个过期的时间即可(目前在浏览器控制台,对服务器下发 cookie 的修改、删除等设置都无效)

4. 安全问题?

客户端修改 cookie,怎么办?

可以设置 HttpOnly 属性,来阻止游览器端通过 document.cookie 访问和操作某个 cookie

给 cookie 加哈希值签名:
签名前:SID=s%3Aefg
签名后:SID=s%3Aefg.7FJDuO2E9LMyby6%2Bo1fGQ3wkIHGB9v1CDVWod8NQVAo(nodejs 示例)
(node.js 使用 cookieParser 中间件签名、解签)

session

1. 是什么?

会话控制,session 对象存储特定用户会话所需的信息

2. 功能?

将重要的会话信息保存在服务器端,比直接使用 cookie 保存在客户端更安全

3. 使用流程?

浏览器首次访问服务器 >>> 服务器生成唯一标识符 sessionID 和存储会话信息的 session 对象,sessionID 放在返回请求头中的 Set-Coookie 中,返回给浏览器 >>> 浏览器携带包含 sessionID 的 cookie 再次访问服务器 >>> 服务器取 cookie 中的 sessionID 继续后续处理

4. 存哪里?

优点 缺点
内存 获取速度快 并发请求多时,服务器内存占用较大,容易造成内存溢出;分布式环境无法实现 session 共享;停电等服务器暂停服务后重启,session 丢失不可恢复
文件 服务器暂停服务后重启,有效期内的 session 仍然可用 获取速度慢;分布式环境,需复制 session 文件至多台服务器
redis 获取速度快;分布式共享;有效期内可找回

cookie vs session

cookie session
存储位置 客户端 服务器
存储内容 ASCII 字符串 任何类型的数据
有效期 可实现长期有效 一般为会话期间有效,不宜过长
安全 客户端透明 客户端不透明
服务器压力 zero 并发用户多时,耗费大量内存 /redis
浏览器支持 禁用 cookie,追踪无效 禁用 cookie,可采用 url 重写

其他文献:

PHP 中的 session: https://www.dragonballsoft.cn…

退出移动版