深入探究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操作Mysql实例代码教程在线版(查询手册)
Feb 18 Python
python多线程扫描端口示例
Jan 16 Python
Python实现统计英文单词个数及字符串分割代码
May 28 Python
让Python更加充分的使用Sqlite3
Dec 11 Python
使用python进行文本预处理和提取特征的实例
Jun 05 Python
浅谈django orm 优化
Aug 18 Python
python在回调函数中获取返回值的方法
Feb 22 Python
python图形工具turtle绘制国际象棋棋盘
May 23 Python
Python适配器模式代码实现解析
Aug 02 Python
python 并发编程 非阻塞IO模型原理解析
Aug 20 Python
使用Django清空数据库并重新生成
Apr 03 Python
Python为何不支持switch语句原理详解
Oct 21 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
PHP5 面向对象(学习记录)
2009/12/02 PHP
PHP实现合并两个排序链表的方法
2018/01/19 PHP
js通过location.search来获取页面传来的参数
2014/09/11 Javascript
Vuex2.0+Vue2.0构建备忘录应用实践
2016/11/30 Javascript
BootStrap导航栏问题记录
2017/07/31 Javascript
vue+webpack实现异步加载三种用法示例详解
2018/04/24 Javascript
使用vuex缓存数据并优化自己的vuex-cache
2018/05/30 Javascript
JS伪继承prototype实现方法示例
2018/06/20 Javascript
JS实现快递单打印功能【推荐】
2018/06/21 Javascript
深入浅析angular和vue还有jquery的区别
2018/08/13 jQuery
webpack@v4升级踩坑(小结)
2018/10/08 Javascript
vue 遮罩层阻止默认滚动事件操作
2020/07/28 Javascript
Python编程中对文件和存储器的读写示例
2016/01/25 Python
Python类属性的延迟计算
2016/10/22 Python
详解Python map函数及Python map()函数的用法
2017/11/16 Python
Python 实现12306登录功能实例代码
2018/02/09 Python
创建Django项目图文实例详解
2019/06/06 Python
Python Multiprocessing多进程 使用tqdm显示进度条的实现
2019/08/13 Python
HTML5之多线程(Web Worker)
2019/01/02 HTML / CSS
白俄罗斯在线大型超市:e-dostavka.by
2019/07/25 全球购物
毕业生动漫设计求职信
2013/10/11 职场文书
校园安全教育广播稿
2014/02/17 职场文书
爱国卫生月实施方案
2014/02/21 职场文书
舞蹈毕业生的自我评价
2014/03/05 职场文书
公司经理聘任书
2014/03/29 职场文书
法律专业自荐信
2014/06/03 职场文书
司法局2014法制宣传日活动总结
2014/11/01 职场文书
2014年工程部工作总结
2014/11/25 职场文书
2015年银行工作总结范文
2015/04/01 职场文书
民事答辩状格式范文
2015/05/21 职场文书
地道战观后感300字
2015/06/04 职场文书
企业催款函范本
2015/06/24 职场文书
Python获取百度热搜的完整代码
2021/04/07 Python
nginx配置文件使用环境变量的操作方法
2021/06/02 Servers
详解运行Python的神器Jupyter Notebook
2021/06/03 Python
Mysql数据库group by原理详解
2022/07/07 MySQL