django框架之cookie/session的使用示例(小结)


Posted in Python onOctober 15, 2018

一、http协议无状态问题

http协议没有提供多次请求之间的关联功能,协议的本意也并未考虑到多次请求之间的状态维持,每一次请求都被协议认为是一次性的。但在某些场景下,如一次登录多次访问,我们希望可以保存登录状态,协议并没有直接提供会话跟踪的支持,需要靠其他手段来帮助实现目标。

二、会话跟踪技术--cookie

1、对cookie的理解

  • cookie是一个key-value的数据结构(类似python字典),用于保存需要维护状态的数据,cookie与session最大的区别是cookie的数据保存在客户端,而session把数据保存在服务端。
  • cookie一般由服务器设置,并可以存放在http的请求头和响应头中。
  • cookie由浏览器保存,浏览器已经实现了cookie的保存和发送,而服务器上对cookie的设置和接收则需要我们配置。
  • 通过cookie,可以在多个会话之间共享一些必要的信息如登录状态数据、历史访问记录、个性化定制设置等,以实现会话跟踪,让用户感觉到网站可以'记录'自己的偏好,减少不必要的重复输入,从而提升用户体验。

2、cookie的使用接口

django的服务端发送响应有三种方式:
1. return HttpResponse()
2. return render()
3. return redirect()

这三种方法实例化的结果都是HttpResponse类的实例,可以直接用于设置cookie。

在response对象上执行set_cookie(key,value,...)即可设置cookie, 其中特别注意cookie属性的设置。

cookie的设置

服务器在响应对象上进行set_cookie操作,一旦设置完成,客户端后续的请求就可以根据cookie的属性规则携带cookie数据。

def set_cookie(key, value='', max_age=None, expires=None, path='/',
        domain=None, secure=False, httponly=False, samesite=None)

cookie的获取

服务器在请求对象上通过request.COOKIES得到cookie字典数据,注意此处拿到的cookie数据从安全性来说是未被验证正确性的。

@cached_property
def COOKIES(self):
  raw_cookie = get_str_from_wsgi(self.environ, 'HTTP_COOKIE', '')
  return parse_cookie(raw_cookie)

注意1:cookie在set的时候可以设置它被发送的范围,每个cookie都有对应的domain+path的属性,这约束了cookie发送范围,只有当http的请求落在此范围中的url,才会携带此cookie。

注意2:一个cookie就是一个key-value项,不过它还携带有属性。一个cookies是一个字典,保存了很多cookie项,注意单个cookie项和整个cookies字典的关系。

3、cookie的属性

max_age:
失效延迟时间,单位是秒,设置成15秒意味着在设置完之后的15秒之内,此cookie有效,超时之后cookie失效,浏览器会删除失效的cookie。此参数默认是None,代表着直到浏览器关闭,即默认是会话cookie。
注意:如果max_age是0,意味着让浏览器立刻删除此cookie,即此cookie即刻失效。

expires:
指定失效日期,同样用于失效cookie,只不过是另一种时间指定方式。

domain:
此cookie可以被使用的域名范围。

path:
与domain配合着使用,默认是根路径'/',意味着在当前domain范围下任何url都会携带此cookie。可以主动设置其他的路径以缩小发送的范围,从而约束某一个cookie项只应用于某些url。

secure:
默认是False,一般配合https协议使用,在https协议下,只有secure属性是True的cookie才允许被发送。

httponly:
默认是False,这意味着js也可以通过document.cookie来访问和设置此cookie,而如果设置为True,则代表只允许服务端来访问和设置此cookie。

4、使用cookie的问题

cookie的安全性问题

服务器是根据客户端发送过来的cookie进行状态判断,这种保存在客户端的cookie数据非常容易修改和伪装,服务器基本无法知晓cookie的正确性,也就不能100%信任cookie的数据。

此外,cookie很容易被盗取,如果客户端cookie里面包含私密数据的话,就更不安全了。

cookie的覆盖问题

在服务端上设置的新的cookie会让客户端更新本地cookie。

cookie的合理性问题

什么样的数据适合放到cookie中?

cookie中的数据是每次交互都要被传输的,所以我认为:

  • 应该是常用的数据,如果不常用只会浪费带宽减少效率,最好是多次交互中都要使用或者修改
  • 应该是小数据量
  • 不应该是非常私密的数据,否则:要么在客户端上容易被盗取,要么在传输中容易被截取

所以cookie特别适合发送sessionid,它能满足上述所有条件。

cookie的存储问题

cookie是客户端临时存储,按规定单个cookie文件存储量最大是4kb,每个域下的cookie文件不能超过20个,不应该将cookie作为存储功能的滥用,要使用客户端存储功能应该启用localstorage。

cookie的访问限制问题

js的document.cookie可以获取cookie数据,将会在控制台输出一个字符串格式的key-value数据,如果此cookie的属性是httponly=true就不能通过此方法获取。

三、会话跟踪技术--session

1、对session的理解

session把数据存放在服务器上,并使用一个标签session-key唯一标记此数据。session-key作为cookie发送给客户端,即客户端只保存session-key,然后通过cookie发送给服务端,以表明身份,所以session比cookie安全。

每一次请求到达服务器的时候,服务器获取cookie中保存的session-key,并在数据库django-session表中寻找对应的session-data,进一步处理业务逻辑。

session的使用有如下优点:
1、数据保存在服务端,客户端仅保存一个senssionid
 2、sessionid数据量很小,适合每次发送
3、安全性,sessionid是一个随机字符串,不携带任何私密数据

2、session的使用接口

session的设置

django实现了session,帮我们完成了很多操作,且提供使用的接口非常简单:

request.session['name'] = 'xxx'

设置session的时候会执行如下三个操作:
1、创建一个随机字符串作为sessionid
2、把sessionid作为session-key,以及一个session_data字典加入到django-session表中
3、set-cookie,把sessionid发送给客户端

注意1:从底层源码来看,session_data其实就是一个字典{},然后通过orm存到django_session表中(应该有dict-->str的序列化和加密操作)

注意2:如果发现客户端的cookie中含有seesionid说明不是第一次登录,将会使用此sessionid并更新此sessionid对应的session_data数据

注意3:如果有两个用户在同一台电脑的同一个浏览器上,访问同一个url,因为sessionid是作为cookie存在,所以两个人会使用同一个sessionid。

而对于服务器而言,只认sessionid不认人,使用同一个sessionid的操作会覆盖之前的数据以导致在服务端上的session_data数据会相互覆盖,这样的结果是数据紊乱(尤其当两人的数据项目数量不一致时更严重)

session的读取

读取session的接口同样很简单:

name = request.session['name']

读取的时候会执行如下三个操作:
1、获取request.COOKIES中的sessionid
2、拿着sessionid作为session_key到数据库的django-session表中查找对应的session-data,底层就是执行orm的objects.filter(session_key=sessionid)
3、获取session-data中的数据并进一步处理

session的删除

删除session的接口:
1、del request.session[xxx]   # 删除一个会话数据属性
2、request.session.flush()    # 删除所有会话数据

清空会话信息时会执行如下操作:
1、删除django-session表中的session-key=sessionid的记录,底层操作就是执行orm的objects.filter(session_key=sessionid).delete()
2、删除response中的cookie里的sessionid记录

注意1:服务器把sessionid作为cookie的数据发给客户端保存,一般是会话cookie即不关闭浏览器程序就可以一直保持会话跟踪。但一旦客户端关闭了浏览器,则此sessionid便不再有效。但django颁发的cookie默认有效时间是2周,所以cookie会被保存到客户端硬盘上,即使关闭了浏览器也继续保存。

注意2:因为服务器无法获知客户端浏览器将会在什么时候关闭,更无法获知浏览器什么时候会执行清空cookie的操作。客户端一般只有在logout的时候才会主动告知删除session,其他情况下浏览器不会主动告知,所以服务器的session不能无限保存,被迫要设置失效时间(不然存储空间浪费),在一定时间内如果还没有用户重新访问此session,便被服务端认为此用户已失效,进而可以删除session数据。

3、session的属性

settings中还可以配置全局的session属性:

# settings.py文件

  SESSION_ENGINE = 'django.contrib.sessions.backends.db'  # 引擎(默认)
  SESSION_COOKIE_NAME = "sessionid"            # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串(默认)
  SESSION_COOKIE_PATH = "/"                # Session的cookie保存的路径(默认)
  SESSION_COOKIE_DOMAIN = None               # Session的cookie保存的域名(默认)
  SESSION_COOKIE_SECURE = False              # 是否Https传输cookie(默认)
  SESSION_COOKIE_HTTPONLY = True              # 是否Session的cookie只支持http传输(默认)
  SESSION_COOKIE_AGE = 1209600               # Session的cookie失效日期(2周)(默认)
  SESSION_EXPIRE_AT_BROWSER_CLOSE = False         # 是否关闭浏览器使得Session过期(默认)
  SESSION_SAVE_EVERY_REQUEST = False            # 是否每次请求都保存Session,默认修改之后才保存(默认)

4、使用session的问题

1、session的正常工作依赖于cookie的启用,如果客户端禁用cookie功能,该如何保证session正常工作?---重写URL

2、同一台电脑同一个浏览器,访问同一个url,保存着同一个sessionid,如何处理多用户使用同一sessionid登录而导致的数据紊乱问题?---使用用户认证组件,使用账户密码来区别用户

四、总结

1、cookie和session都是为了解决http协议自身并不支持状态维持的缺点。
2、会话跟踪的目的是为了让多次请求之间可以共享数据,以提供更好的用户体验。
3、cookie和session都需要保存状态维持数据,只不过cookie是保存在客户端,session是保存在服务端。
4、分析和研究两者的技术相同点和区别有助于加深对会话跟踪的理解和使用。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python中常用信号signal类型实例
Jan 25 Python
Python编程求质数实例代码
Jan 31 Python
Django JWT Token RestfulAPI用户认证详解
Jan 23 Python
python 二维数组90度旋转的方法
Jan 28 Python
使用Python实现毫秒级抢单功能
Jun 06 Python
Python之修改图片像素值的方法
Jul 03 Python
详解Django 时间与时区设置问题
Jul 23 Python
深入了解python中元类的相关知识
Aug 29 Python
tensorflow使用range_input_producer多线程读取数据实例
Jan 20 Python
Spring Boot中使用IntelliJ IDEA插件EasyCode一键生成代码详细方法
Mar 20 Python
python实现飞船游戏的纵向移动
Apr 24 Python
Pytorch 使用tensor特定条件判断索引
Apr 08 Python
Python访问MongoDB,并且转换成Dataframe的方法
Oct 15 #Python
Django框架的中的setting.py文件说明详解
Oct 15 #Python
python得到电脑的开机时间方法
Oct 15 #Python
python得到单词模式的示例
Oct 15 #Python
详解python如何在django中为用户模型添加自定义权限
Oct 15 #Python
Python 实现某个功能每隔一段时间被执行一次的功能方法
Oct 14 #Python
Python 实现异步调用函数的示例讲解
Oct 14 #Python
You might like
php smarty模版引擎中的缓存应用
2009/12/02 PHP
基于PHP给大家讲解防刷票的一些技巧
2015/11/18 PHP
在html页面上拖放移动标签
2010/01/08 Javascript
jQuery实现form表单reset按钮重置清空表单功能
2012/12/18 Javascript
JS控件ASP.NET的treeview控件全选或者取消(示例代码)
2013/12/16 Javascript
jQuery.event兼容各浏览器的event详细解析
2013/12/18 Javascript
Bootstrap表格和栅格分页实例详解
2016/05/20 Javascript
Angular的事件和表单详解
2016/12/26 Javascript
angular实现商品筛选功能
2017/02/01 Javascript
jquery表单提交带错误信息提示效果
2017/03/09 Javascript
推荐三款日期选择插件(My97DatePicker、jquery.datepicker、Mobiscroll)
2017/04/21 jQuery
关于Angular2 + node接口调试的解决方案
2017/05/28 Javascript
使用typescript开发angular模块并发布npm包
2018/04/19 Javascript
微信小程序template模版的使用方法
2019/04/13 Javascript
vue路由对不同界面进行传参及跳转的总结
2019/04/20 Javascript
解决mui框架中switch开关通过js控制开或者关状态时小圆点不动的问题
2019/09/03 Javascript
js实现数字滚动特效
2019/12/16 Javascript
ES6函数和数组用法实例分析
2020/05/23 Javascript
antd design table更改某行数据的样式操作
2020/10/31 Javascript
[36:17]DOTA2上海特级锦标赛 - VGL音乐会全集
2016/03/06 DOTA
Python基于opencv的图像压缩算法实例分析
2018/05/03 Python
利用python如何在前程无忧高效投递简历
2019/05/07 Python
解决Django一个表单对应多个按钮的问题
2019/07/18 Python
纯CSS3实现的阴影效果
2014/12/24 HTML / CSS
英国PC组件和在线电脑商店:SCAN
2019/04/18 全球购物
Parfumdreams英国:香水和化妆品
2019/05/10 全球购物
如何删除一个表里面的重复行
2013/07/13 面试题
中学门卫岗位职责
2013/12/26 职场文书
学生自我鉴定模板
2013/12/30 职场文书
大学生家政服务项目创业计划书
2014/01/30 职场文书
2015年南京大屠杀纪念日活动总结
2015/03/24 职场文书
酒店总经理岗位职责
2015/04/01 职场文书
2015年技术员工作总结
2015/04/10 职场文书
给老师的保证书怎么写
2015/05/09 职场文书
2015年妇产科工作总结
2015/05/18 职场文书
五星红旗迎风飘扬观后感
2015/06/17 职场文书