由于Web及HTTP的短连接性,Cookie和Session是使用户会话持久化的两种技术。
Cookie
Cookie是由浏览器维持的,存储在客户端的一小段文本信息
Cookie是有时间限制的,根据生命期不同分成两种:会话Cookie和持久Cookie;
如果不设置过期时间,则表示这个Cookie生命周期为从创建到浏览器关闭止,这种Cookie一般保存在内存中。
如果设置了过期时间,浏览器就会把Cookie保存到硬盘上,关闭后再次打开浏览器,这些Cookie依然有效直到超过设定的过期时间。存储在硬盘上的Cookie可以在不同的浏览器进程间共享,而内存里的Cookie就不一定了。
golang中Cookie的标准定义
// See http://tools.ietf.org/html/rfc6265 for details.
type Cookie struct {
Name string
Value string
Path string // optional
Domain string // optional
Expires time.Time // optional
RawExpires string // for reading cookies only
// MaxAge=0 means no 'Max-Age' attribute specified.
// MaxAge<0 means delete cookie now, equivalently 'Max-Age: 0'
// MaxAge>0 means Max-Age attribute present and given in seconds
MaxAge int
Secure bool
HttpOnly bool
Raw string
Unparsed []string // Raw text of unparsed attribute-value pairs
}
通过插件抓取网页的具体cookie:
介绍下hostOnly这个flag,就是指Cookie只能在完全匹配域名的时候才能获取到,Domain属性为example.com的Cookie只有在example.com才有可能获取到。host-only-flag为false时,Domain属性为example.com的Cookie,在example.com、www.example.com、sub.example.com等等都可能获取到。但是host-only-flag没有直接设置的值。
至于HttpOnly,就是指这个cookie只能被用来进行http请求,不能被浏览器的API使用,比如被script获取,这也是为了安全性。
Session
session机制是一种服务器端的机制,服务器使用一种类似于散列表的结构(也可能就是使用散列表)来保存信息。
程序需要为某个客户端的请求创建一个session的时候,服务器首先检查这个客户端的请求里是否包含了一个session标识-称为session id,如果已经包含一个session id则说明以前已经为此客户创建过session,服务器就按照session id把这个session检索出来使用。如果客户请求不包含session id,则为此客户创建一个session并且同时生成一个与此session相关联的session id,这个session id将在本次响应中返回给客户端保存。
而使用session的方法有两种,cookie和URL重写
Cookie就是通过Set-cookie头,将session的标识符传送给客户端,之后客户端每次请求都会自动带上这个标识符,一般这类cookie的失效时间为0
URL重写,就是给用户返回的页面里的所有URL后面追加一个session标识符,这样用户不管桌面GET、POST都会自动带上session,虽然很麻烦,但是可以避免cookie被禁用的尴尬。
为了防止sessionID被劫持,可以有两种解决方案:
1. 只允许cookie设置,不用URL重写,并且将cookie设置为httponly,防止客户端脚本访问这个cookie,避免xss获得这个cookie。
2. 在每个请求里添加一个token,每次验证这个token
还有就是可以间隔时间生成新的sessionID。
总结
session和cookie的目的相同,都是为了克服http协议无状态的缺陷,但完成的方法不同。session通过cookie,在客户端保存session id,而将用户的其他会话消息保存在服务端的session对象中,与此相对的,cookie需要将所有信息都保存在客户端。