Http协议
请求和响应
Http协议用于客户端与服务端的通信,客户端发出请求,服务端返回响应。下面我们以访问https://www.sogou.com/搜狗首页为例,来看看请求报文和响应报文:
下面是从客户端访问服务器的请求报文的截取内容:
GET / HTTP/1.1
Host: www.sogou.com
Connection: keep-alive
Cache-Control: max-age=0
第一行的GET表示请求方法;随后的 / 表示请求访问的资源对象(request-URI),这里是根页面;最后的HTTP/1.1是协议和版本号。
第二行开始是首部字段:Host字段表示服务器域名。(这里只截取了部分首部字段,实际的字段更多)
http请求报文由请求方法、URI、HTTP版本、HTTP首部字段构成。
下面是服务器返回的响应报文的截取内容:
HTTP/1.1 200 OK
Server: nginx
Date: Tue, 19 Sep 2017 08:37:38 GMT
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
<html>
......
第一行的HTTP/1.1表示服务器对应的HTTP版本; 200 OK表示请求处理结果的状态码和原因短语。
第二行开始是首部字段,包括服务器安装的软件版本,响应日期等。
响应报文包括响应头和响应体。
响应头由HTTP版本、状态码、原因短语、首部字段组成。
最下面的<html>
开始是响应体,也就是用户在浏览器上看到的具体网页,由两组\r\n
换行符与上面的响应头分隔。
http是无状态协议
使用http协议通信时,每当有新请求到达时,就会有对应的新的响应产生。http协议本身并不保留之前的一切请求或响应报文的信息。这是为了更快地处理大量事物,确保协议的可伸缩性,也能减轻服务器的压力。而且由于不需要保存状态,http协议本身比较简单,能被应用在各种场景里。
但是这种无状态的特征,导致要求登录认证的web页面无法记录用户的已登录状态,用户每次跳转到新页面都要重新登录。
使用Cookie和Session管理状态
既要保留http无状态的特征,又要记录用户的登录状态,于是引入了Cookie技术。服务器在响应头部中加入Set-Cookie字段,通知客户端(浏览器)保存Cookie,下次客户端再发送请求时,在请求头部中加入这Cookie后发送出去。服务器通过判断客户端发过来的Cookie,就能知道来的人是谁。
cookie虽然解决了保存状态的需求,但是cookie也有限制:
- cookie最大支持4096字节,记录的信息有限
- cookie本身保存在客户端,安全性不足
基于以上两点,需要某种新的东西,它能支持更多的字节,并且保存在服务器,拥有更高的安全性,这就是session。
session是通过cookie来管理的,服务器在响应头部的Set-Cookie字段中向请求用户发放Session ID;现在cookie不在本地保存用户的敏感信息,只保存一个代表用户身份的令牌(Session ID);当用户再次发送请求时,只需发送包含Session ID的Cookie,服务器通过Session ID取出保存在服务器上的用户信息。
cookie 的安全性问题可以通过签名/加密cookie来解决,具体可以参考:
http://blog.csdn.net/ayhan_huang/article/details/78202817
总结:
- cookie是保存在浏览器的键值对
- session是保存在服务端的键值对
- session依赖于cookie
Cookie和Session配合使用
cookie和session储存数据是通过键值对的方式,因此我们可以像操作字典一样,来写入或读取数据:
用户发起请求:
- 写浏览器cookie: {session_id: ‘随机字符串’}
用户认证成功后:
写入用户信息到服务器session:
{ '随机字符串': {key: value,......}, }
因此,每次用户请求都在cookie中携带session_id这个令牌,服务器根据session_id的值,从服务器中取出用户的信息。
Django中操作cookie
拿到请求的cookie信息:
cookie_info = request.COOKIES
从请求对象中提取加盐cookie:
request.get_signed_cookie("key",salt="mysaltstr");
在响应对象上写入cookie:
先拿到响应对象:
response_obj=redirect("/url_path/")
response_obj=HttpResponse("content")
response_obj=render(request,"html")
在响应对象上设置cookie:
response_obj.set_cookie("key","value",max_age=60)
设置加盐cookie:
response_obj.set_signed_cookie("key","value",max_age=60, salt="mysaltstr")
Django中操作session
设置session字典内容:
request.session[key] = value
提取session字典内容:
request.session.get[key]
删除session:
del request.session[key]