深入探究Django中的Session与Cookie


Posted in Python onJuly 30, 2017

前言

Cookie和Session相信对大家来说并不陌生,简单来说,Cookie和Session都是为了记录用户相关信息的方式,最大的区别就是Cookie在客户端记录而Session在服务端记录内容。

那么Cookie和Session之间的联系是怎么建立的呢?换言之,当服务器接收到一个请求时候,根据什么来判断读取哪个Session的呢?

对于Django默认情况来说,当用户登录后就可以发现Cookie里有一个sessionid的字段,根据这个key就可以取得在服务器端记录的详细内容。如果将这个字段删除,刷新页面就会发现变成未登录状态了。

对于Session的处理主要在源码django/contrib/sessions/middleware.py中,如下所示:

import time
from importlib import import_module
from django.conf import settings
from django.contrib.sessions.backends.base import UpdateError
from django.core.exceptions import SuspiciousOperation
from django.utils.cache import patch_vary_headers
from django.utils.deprecation import MiddlewareMixin
from django.utils.http import cookie_date
class SessionMiddleware(MiddlewareMixin):
 def __init__(self, get_response=None):
  self.get_response = get_response
  engine = import_module(settings.SESSION_ENGINE)
  self.SessionStore = engine.SessionStore
 def process_request(self, request):
  session_key = request.COOKIES.get(settings.SESSION_COOKIE_NAME)
  request.session = self.SessionStore(session_key)
 def process_response(self, request, response):
  """
  If request.session was modified, or if the configuration is to save the
  session every time, save the changes and set a session cookie or delete
  the session cookie if the session has been emptied.
  """
  try:
   accessed = request.session.accessed
   modified = request.session.modified
   empty = request.session.is_empty()
  except AttributeError:
   pass
  else:
   # First check if we need to delete this cookie.
   # The session should be deleted only if the session is entirely empty
   if settings.SESSION_COOKIE_NAME in request.COOKIES and empty:
    response.delete_cookie(
     settings.SESSION_COOKIE_NAME,
     path=settings.SESSION_COOKIE_PATH,
     domain=settings.SESSION_COOKIE_DOMAIN,
    )
   else:
    if accessed:
     patch_vary_headers(response, ('Cookie',))
    if (modified or settings.SESSION_SAVE_EVERY_REQUEST) and not empty:
     if request.session.get_expire_at_browser_close():
      max_age = None
      expires = None
     else:
      max_age = request.session.get_expiry_age()
      expires_time = time.time() + max_age
      expires = cookie_date(expires_time)
     # Save the session data and refresh the client cookie.
     # Skip session save for 500 responses, refs #3881.
     if response.status_code != 500:
      try:
       request.session.save()
      except UpdateError:
       raise SuspiciousOperation(
        "The request's session was deleted before the "
        "request completed. The user may have logged "
        "out in a concurrent request, for example."
       )
      response.set_cookie(
       settings.SESSION_COOKIE_NAME,
       request.session.session_key, max_age=max_age,
       expires=expires, domain=settings.SESSION_COOKIE_DOMAIN,
       path=settings.SESSION_COOKIE_PATH,
       secure=settings.SESSION_COOKIE_SECURE or None,
       httponly=settings.SESSION_COOKIE_HTTPONLY or None,
      )
  return response

当接收到一个请求时候,先在Cookie里取出key,然后根据key创建Session对象,在response时候判断是否要删除或者修改sessionid。

也就是说,Django中如果客户把浏览器Cookie禁用后,用户相关的功能就全都失效了,因为服务端根本没法知道当前用户是谁。

对于这种情况,关键点就是如何把sessionid不使用Cookie传递给客户端,常见的比如放在URL中,也就是URL重写技术。想实现这点可以自己写Middleware。不过django并不建议这么做:

The Django sessions framework is entirely, and solely, cookie-based. It does not fall back to putting session IDs in URLs as a last resort, as PHP does. This is an intentional design decision. Not only does that behavior make URLs ugly, it makes your site vulnerable to session-ID theft via the “Referer” header.

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持

Python 相关文章推荐
python使用PyFetion来发送短信的例子
Apr 22 Python
Python随机生成数模块random使用实例
Apr 13 Python
Django实现的自定义访问日志模块示例
Jun 23 Python
python+pyqt实现12306图片验证效果
Oct 25 Python
Python3中内置类型bytes和str用法及byte和string之间各种编码转换 问题
Sep 27 Python
用Python中的turtle模块画图两只小羊方法
Apr 09 Python
用python建立两个Y轴的XY曲线图方法
Jul 08 Python
python中rc1什么意思
Jun 19 Python
终于搞懂了Keras中multiloss的对应关系介绍
Jun 22 Python
python复合条件下的字典排序
Dec 18 Python
pytorch中的model=model.to(device)使用说明
May 24 Python
浅析Python OpenCV三种滤镜效果
Apr 11 Python
python中numpy包使用教程之数组和相关操作详解
Jul 30 #Python
利用Python批量压缩png方法实例(支持过滤个别文件与文件夹)
Jul 30 #Python
Python利用BeautifulSoup解析Html的方法示例
Jul 30 #Python
利用python获取当前日期前后N天或N月日期的方法示例
Jul 30 #Python
Python 装饰器使用详解
Jul 29 #Python
python实现数据图表
Jul 29 #Python
基于Python的XSS测试工具XSStrike使用方法
Jul 29 #Python
You might like
定制404错误页面,并发信给管理员的程序
2006/10/09 PHP
PHP输出时间差函数代码
2013/01/28 PHP
PHP实现批量修改文件后缀名的方法
2015/07/30 PHP
PHP预定义超全局数组变量小结
2018/08/20 PHP
Discuz! 6.1_jQuery兼容问题
2008/09/23 Javascript
JavaScript中的继承方式详解
2015/02/11 Javascript
jQuery 判断图片是否加载完成方法汇总
2015/08/10 Javascript
jquery图片倾斜层叠切换特效代码分享
2015/08/27 Javascript
jQuery实现宽屏图片轮播实例教程
2015/11/24 Javascript
js HTML5多媒体影音播放
2016/10/17 Javascript
Vue.js仿微信聊天窗口展示组件功能
2017/08/11 Javascript
Javascript中的作用域及块级作用域
2017/12/08 Javascript
详解Vue结合后台的列表增删改案例
2018/08/21 Javascript
vue动态禁用控件绑定disable的例子
2019/10/28 Javascript
ES6 Iterator遍历器原理,应用场景及相关常用知识拓展详解
2020/02/15 Javascript
javascript实现计算器功能
2020/03/30 Javascript
vue实现图片上传功能
2020/05/28 Javascript
浅谈js中的attributes和Attribute的用法与区别
2020/07/16 Javascript
[02:49]2018DOTA2亚洲邀请赛主赛事决赛日战况回顾 Mineski鏖战5局夺得辉耀
2018/04/10 DOTA
Python实现子类调用父类的方法
2014/11/10 Python
使用Python读取安卓手机的屏幕分辨率方法
2018/03/31 Python
Django框架登录加上验证码校验实现验证功能示例
2019/05/23 Python
Python使用urllib模块对URL网址中的中文编码与解码实例详解
2020/02/18 Python
使用Python将Exception异常错误堆栈信息写入日志文件
2020/04/08 Python
python实现npy格式文件转换为txt文件操作
2020/07/01 Python
Python开发入门——迭代的基本使用
2020/09/03 Python
python中操作文件的模块的方法总结
2021/02/04 Python
HTML5所有标签汇总及标签意义解释
2015/03/12 HTML / CSS
英国最大的在线运动补充剂商店:Discount Supplements
2017/06/03 全球购物
瑜伽灵感珠宝:Satya Jewelry
2018/01/06 全球购物
世界上最大的隐形眼镜商店:1-800 Contacts
2018/11/03 全球购物
Moda Operandi官网:美国奢侈品电商,海淘秀场T台同款
2020/05/26 全球购物
师恩难忘教学反思
2014/04/27 职场文书
营销总经理岗位职责范本
2014/09/02 职场文书
临时用工协议书范本
2014/10/29 职场文书
安全责任书
2015/01/29 职场文书