在网站中,http请求是无状态的。即服务器不知道用户上一次做了什么,也就是说即使第一次和服务器连接后并且登录成功后,第二次请求服务器依然不能知道当前请求是哪个用户,之前做了什么操作。
典型的场景比如购物车,当你点击下单按钮时,由于HTTP协议无状态,所以根本就不知道是哪个用户操作,也不知道购物车里面都有哪些商品
所以当服务端需要记录用户的状态时,就要用某种机制来进行识别和记录,这也就是cookie和session
区别是,session多是存储在服务器中,cookie多是存储在客户端中
## session
### session详解
session代表服务器与浏览器的一次会话过程,这个过程可以是连续的,也可以时断时续的。
session 是一个思路、一个概念、一个服务器存储授权信息的解决方案,不同的服务器,不同的框架,不同的语言等都有不同的实现。
session是服务器生成的,有一个唯一标识。在服务端保存Session的方法很多,内存、数据库、文件等等。集群的时候也要考虑session的转移,在大型的网站,一般会有专门的session服务器集群,用来保存用户会话,这个时候 session 信息都是放在内存的,使用一些缓存服务比如memcached之类的来放session。
### session工作原理
#### 1. 创建session
当用户访问到一个服务器,如果服务器启用session,服务器就要为该用户创建一个SESSION,在创建这个SESSION的时候,服务器首先检查这个用户发来的请求里是否包含了一个SESSION ID,如果包含了一个SESSION ID则说明之前该用户已经登陆过并且服务器已经为此用户创建过SESSION,那服务器就按照这个SESSION ID把这个SESSION检索出来使用(如果检索不到,就有可能为他新创建一个),如果客户端请求里不包含有SESSION ID,则为该客户端创建一个SESSION并生成一个与此SESSION相关的SESSION ID。这个SESSION ID是唯一的、不重复的、不容易找到规律的字符串,这个SESSION ID将被在本次响应中返回到客户端保存,而保存这个SESSION ID的正是COOKIE,这样在交互过程中浏览器可以自动的按照规则把这个标识发送给服务器。
#### 2. 使用session
SESSION ID 保存在cookie中,所以当浏览器再次访问该网站时,会在请求头中携带cookie访问,服务器接收到cookie并解析出SESSION ID,并根据SESSION ID 找到相对应的SESSION
但是在浏览器选项中可以将cookie禁止,那么会不会出现把客户端的cookie禁止,然后SESSION ID 无法再用的情况呢?
SESSION ID 仍然有其他机制在cookie被禁止时传回服务器
经常被使用的一种技术是 **URL重写**, 就是把Session id直接附加在URL路径的后面作为URL路径的附加信息,表现形式为:
http://…./xxx;jSession=ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764;
另一种是作为查询字符串附加在URL后面,表现形式为:
http://…../xxx?jSession=ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764
还有一种就是表单隐藏字段,服务器会自动修改表单,添加一个隐藏字段,以便在表单提交时能够把Session id传递回服务器
### session的优缺点
## cookie
### cookie详解
Cookie(复数形态:Cookies),是指某些网站为了辨别用户身份、进行session跟踪而储存在用户本地终端上的数据(通常经过加密)。
cookie 存储的数据量有限,不同的浏览器有不同的存储大小,但一般不超过4KB。因此使用 cookie 只能存储一些小量的数据。
cookie是有时间限制的,根据生命期不同分成两种:会话cookie和持久cookie;
如果不设置过期时间,则表示这个cookie生命周期为从创建到浏览器关闭止,只要关闭浏览器窗口,cookie就消失了。这种生命期为浏览会话期的cookie被称为会话cookie。会话cookie一般不保存在硬盘上而是保存在内存里。
如果设置了过期时间(MaxAge),浏览器就会把cookie保存到硬盘上,关闭后再次打开浏览器,这些cookie依然有效直到超过设定的过期时间。存储在硬盘上的cookie可以在同一个浏览器的不同进程间共享,比如两个IE窗口。而对于保存在内存的cookie,不同的浏览器有不同的处理方式。
### cookie工作原理
#### 1. 创建cookie
当用户第一次浏览某个使用Cookie的网站时,该网站的服务器就进行如下工作:
1. 为该用户生成一个唯一的识别码(Cookie id),创建一个Cookie对象;
2. 默认情况下它是一个会话级别的cookie,存储在浏览器的内存中,用户退出浏览器之后被删除。如果服务器希望浏览器将该Cookie存储在磁盘上,则需要设置最大时效(maxAge),并给出一个以秒为单位的时间(将最大时效设为0则是命令浏览器删除该Cookie)
3. 将Cookie放入到HTTP响应报头,将Cookie插入到一个 Set-Cookie HTTP请求报头中
4. 发送该HTTP响应报文
#### 2. 设置存储cookie
浏览器收到该响应报文之后,根据报文头里的Set-Cookied特殊的指示,生成相应的Cookie,保存在客户端。该Cookie里面记录着用户当前的信息
#### 3. 发送cookie
当用户再次访问该网站时,浏览器首先检查所有存储的cookies,如果存在该网站的cookie,则把该cookie附在请求资源的HTTP请求头上发送给服务器
#### 4. 读取cookie
服务器接收到用户的HTTP请求报文之后,从报文头获取到该用户的Cookie,从里面找到所需要的东西。
### cookie的优缺点
## cookie和session的使用
web 开发发展至今, cookie 和 session 的使用已经出现了一些非常成熟的方案。在如今的市场或者企业里,一般有两种存储方式:
- 存储在服务端:
通过 cookie 存储一个 sessionid ,然后具体的数据则是保存在 session 中。如果用户已经登录,则服务器会在 cookie 中保存一个 sessionid ,下次再次请求的时候,会把该 sessionid 携带上来,服务器根据 sessionid 在 session 库中获取用户的 session 数据。就能知道该用户到底是谁,以及之前保存的一些状态信息。这种专业术语叫做 server sidesession 。 Django 把 session 信息默认存储到数据库中,当然也可以存储到其他地方,比如缓存中,文件系统中等。存储在服务器的数据会更加的安全,不容易被窃取。但存储在服务器也有一定的弊端,就是会占用服务器的资源,但现在服务器已经发展至今,处理一些 session 信息还是绰绰有余的。
- 将 session 数据加密,然后存储在 cookie 中。
这种专业术语叫做 client side session 。 flask 框架默认采用的就是这种方式,但是也可以替换成其他形式。