会话
会话(Session)跟踪是Web程序中常用的技术,用来跟踪用户的整个会话,由于HTTP是无状态协议,无法得知两次请求是来自同一个会话,所以需要额外的技术来跟踪会话。常用的会话跟踪技术是Cookie与Session。Cookie通过在客户端记录信息确定用户身份,Session通过在服务器端记录信息确定用户身份。
COOKIE
什么是COOKIE
Cookie意为“甜饼”,是由W3C组织提出,最早由Netscape社区发展的一种机制。
Cookie实际上是一小段的文本信息,存储在用户本地终端。客户端请求服务器,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个Cookie。客户端浏览器会把Cookie保存起来。当浏览器再请求该网站时,浏览器把请求的网址连同该Cookie一同提交给服务器。
组成
Cookie是一段不超过4KB的小型文本数据,由一个名称(Name)、一个值(Value)和其它几个用于控制Cookie有效期、安全性、使用范围的可选属性组成,具体属性如下:
属性名 | 类型 | 描述 |
---|---|---|
Name | String | Cookie的名称,一旦创建,不可更改 |
Value | Object | Cookie的值,如果值为Unicode字符,需要为字符编码。如果为二进制数据,则需要使用BASE64编码 |
Max-Age | Integer | Cookie失效的时间,单位秒。如果为正数,则Cookie在Max-Age秒之后失效。如果为负数,该Cookie为临时Cookie,关闭浏览器即失效,浏览器也不会以任何形式保存该Cookie。如果为0,表示删除该Cookie。默认为–1。注意:该时间与客户端系统时间作比较而不是服务器时间 |
Secure | Boolean | 是否只在HTTPS中发送Cookie,默认为False |
Path | String | 定义Web站点上可以访问该Cookie的目录,如果设置为“/webCookie/”,则只有contextPath为“/webCookie”的程序可以访问该Cookie,设置为“/”则都可以访问,注意最后一个字符必须为“/”,默认情况下为产生cookie时的路径(疑问:完整匹配还是前缀匹配) |
Domain | String | 指定可以访问该Cookie的域名。如果设置为“.google.com”,则所有以“google.com”结尾的域名都可以访问该Cookie。注意第一个字符必须为“.” |
HTTPOnly | boolean | 用于防止客户端脚本通过document.cookie属性访问Cookie,但是,HTTPOnly的应用仍存在局限性,一些浏览器可以阻止客户端脚本对Cookie的读操作,但允许写操作;此外大多数浏览器仍允许通过XMLHTTP对象读取HTTP响应中的Set-Cookie头 |
Comment | String | Cookie的描述信息,相当于注释 |
Version | String | 定义cookie的版本,由cookie的创建者定义 |
Cookie的修改与删除
Cookie并不提供修改、删除操作。如果要修改某个Cookie,只需要新建一个同名的Cookie,添加到response中覆盖原来的Cookie。
如果要删除某个Cookie,只需要新建一个同名的Cookie,并将maxAge设置为0,并添加到response中覆盖原来的Cookie。注意是0而不是负数。负数代表其他的意义。读者可以通过上例的程序进行验证,设置不同的属性。
注意:修改、删除Cookie时,新建的Cookie除value、maxAge之外的所有属性,例如name、path、domain等,都要与原Cookie完全一样。否则,浏览器将视为两个不同的Cookie不予覆盖,导致修改、删除失败。
Cookie跨域
- nginx反代欺骗浏览器
- jsonp
- p3p
COOKIE的应用
使用Cookie跟踪广告和图片使用情况
SESSION
Session是另一种记录客户状态的机制,不同的是Cookie保存在客户端浏览器中,而Session保存在服务器上。
针对Web网站来说,Session指用户在浏览某个网站时,从进入网站到浏览器关闭这段时间内的会话。
SESSION通过SESSION_ID来识别不同会话,即Session文件的文件名,而SESSION_ID默认是通过COOKIE传递。
假设客户端禁用Cookie,可以通过URL或者隐藏表单传递sessionID;php.ini中把session.use_trans_sid 设成1,那么连接后就会自己加Session的ID。
cookie和session的区别
- 存放位置不同
- Cookie存放于客户端,Session存放于服务器
- 过多Session数据会占用服务器资源,Cookie存放在客户端没有,分摊后压力很小
- 安全性
- 由于COOKIE存储在客户端,用户可以随意更改,因此安全性相对较差,使用时需要验证数据合法性(数据签名)
- 为避免拷贝其他用户COOKIE过来直接使用,也就是COOKIE劫持,需要在Cookie中针对IP、UA等加上特殊的校验信息,然后和服务器端进行比对。
- 存储大小不同
- 单个cookie保存的数据不能超过4K,原始规范要求一个站点最多保存20个cookie,实际很多浏览器限制都不同,但都大于20。
- session没有存储大小和数量限制
SESSION共享
- nginx ip hash 负载均衡(尽量让同一用户访问同一服务器,在移动端时代效果不好)
- session复制,例如基于tomcat的session复制
- 使用redis作统一缓存sessionid对应的信息,避免session复制,需要改代码,增加一次网络开销
- 使用jwt,将登陆信息加密存储到客户端缓存中(目前比较通用的解决方案)
参考文章 【详解 Cookie 纪要】
参考文章 【cookie和session的详解与区别】