深入探究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中用于转换字母为小写的lower()方法使用简介
May 19 Python
Python引用模块和查找模块路径
Mar 17 Python
python-opencv在有噪音的情况下提取图像的轮廓实例
Aug 30 Python
Python基于更相减损术实现求解最大公约数的方法
Apr 04 Python
Python continue继续循环用法总结
Jun 10 Python
基于python实现名片管理系统
Nov 30 Python
python 随机打乱 图片和对应的标签方法
Dec 14 Python
Python3实现对列表按元组指定列进行排序的方法分析
Dec 22 Python
python ChainMap 合并字典的实现步骤
Jun 11 Python
Python 微信爬虫完整实例【单线程与多线程】
Jul 06 Python
Python爬虫之爬取哔哩哔哩热门视频排行榜
Apr 28 Python
python 网络编程要点总结
Jun 18 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
Ajax+PHP 边学边练 之二 实例
2009/11/24 PHP
php一个找二层目录的小东东
2012/08/02 PHP
PHP获取搜索引擎关键字来源的函数(支持百度和谷歌等搜索引擎)
2012/10/03 PHP
解析WordPress中的post_class与get_post_class函数
2016/01/04 PHP
php求数组全排列,元素所有组合的方法
2016/05/05 PHP
PHP开发的文字水印,缩略图,图片水印实现类与用法示例
2019/04/12 PHP
jquery 应用代码 方便的排序功能
2010/02/06 Javascript
jquery.hotkeys监听键盘按下事件keydown插件
2014/05/11 Javascript
让JavaScript和其它资源并发下载的方法
2014/10/16 Javascript
js实现鼠标点击文本框自动选中内容的方法
2015/08/20 Javascript
APP中javascript+css3实现下拉刷新效果
2016/01/27 Javascript
修复jQuery tablesorter无法正确排序的bug(加千分位数字后)
2016/03/30 Javascript
jquery制做精致的倒计时特效
2016/06/13 Javascript
javascript 动态脚本添加的简单方法
2016/10/11 Javascript
jQueryeasyui 中如何使用datetimebox 取两个日期间相隔的天数
2017/06/13 jQuery
解决VUEX刷新的时候出现数据消失
2017/07/03 Javascript
nodejs中方法和模块用法示例
2018/12/24 NodeJs
微信小程序实现时间进度条功能
2020/11/17 Javascript
react-router-dom 嵌套路由的实现
2020/05/02 Javascript
解决vue cli4升级sass-loader(v8)后报错问题
2020/07/30 Javascript
python使用递归解决全排列数字示例
2014/02/11 Python
Python的Twisted框架中使用Deferred对象来管理回调函数
2016/05/25 Python
Python+微信接口实现运维报警
2016/08/27 Python
Python文件读写保存操作的示例代码
2018/09/14 Python
python复制列表时[:]和[::]之间有什么区别
2018/10/16 Python
Python模块/包/库安装的六种方法及区别
2020/02/24 Python
解决python多线程报错:AttributeError: Can't pickle local object问题
2020/04/08 Python
悦木之源美国官网:Origins美国
2016/08/01 全球购物
自我鉴定范文300字
2013/10/01 职场文书
阳光体育活动方案
2014/02/16 职场文书
群众路线调研报告范文
2014/11/03 职场文书
幼儿园六一主持词开场白
2015/05/28 职场文书
心得体会格式及范文
2016/01/25 职场文书
Python字典和列表性能之间的比较
2021/06/07 Python
从QQtabBar看css命名规范BEM的详细介绍
2021/08/07 HTML / CSS
springboot中rabbitmq实现消息可靠性机制详解
2021/09/25 Java/Android