深入探究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实现简单字典树的方法
Apr 29 Python
浅谈Python类的__getitem__和__setitem__特殊方法
Dec 25 Python
Python基于numpy灵活定义神经网络结构的方法
Aug 19 Python
Selenium定位元素操作示例
Aug 10 Python
Python 的AES加密与解密实现
Jul 09 Python
基于MATLAB和Python实现MFCC特征参数提取
Aug 13 Python
python 修改本地网络配置的方法
Aug 14 Python
flask框架自定义url转换器操作详解
Jan 25 Python
Python如何避免文件同名产生覆盖
Jun 09 Python
解析Tensorflow之MNIST的使用
Jun 30 Python
Django Form设置文本框为readonly操作
Jul 03 Python
Python 操作 MySQL数据库
Sep 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
雄兵连:第三季确定会出,不过时间未定,鹤熙是第三季的主角!
2020/03/13 国漫
php解析url的三个示例
2014/01/20 PHP
PHP查找与搜索数组元素方法总结
2015/06/12 PHP
php parse_str() 函数的定义和用法
2016/05/23 PHP
Laravel框架路由管理简单示例
2019/05/07 PHP
extjs 列表框(multiselect)的动态添加列表项的方法
2009/07/31 Javascript
一些主流JS框架中DOMReady事件的实现小结
2011/02/12 Javascript
jQuery的Ajax用户认证和注册技术实例教程(附demo源码)
2015/12/08 Javascript
全面解析Bootstrap中scrollspy(滚动监听)的使用方法
2016/06/06 Javascript
jquery常用的12个小功能
2016/07/22 Javascript
原生JS实现《别踩白块》游戏(兼容IE)
2017/02/20 Javascript
详谈js使用in和hasOwnProperty获取对象属性的区别
2017/04/25 Javascript
浅谈vue.js导入css库(elementUi)的方法
2018/03/09 Javascript
JavaScript使用indexOf()实现数组去重的方法分析
2018/09/04 Javascript
纯js+css实现在线时钟
2020/08/18 Javascript
Openlayers实现地图全屏显示
2020/09/28 Javascript
在vue中使用Echarts画曲线图的示例
2020/10/03 Javascript
vue 数据双向绑定的实现方法
2021/03/04 Vue.js
[01:59]深扒TI7聊天轮盘语音出处 1
2017/05/11 DOTA
python实现电子词典
2020/04/23 Python
python 写入csv乱码问题解决方法
2016/10/23 Python
python模块之time模块(实例讲解)
2017/09/13 Python
Python基于ThreadingTCPServer创建多线程代理的方法示例
2018/01/11 Python
在python中pandas的series合并方法
2018/11/12 Python
python Pandas库基础分析之时间序列的处理详解
2019/07/13 Python
Tensorflow累加的实现案例
2020/02/05 Python
Python异常处理机制结构实例解析
2020/07/23 Python
芬兰汽车配件商店:Autonvaraosat24
2017/01/30 全球购物
东芝官网商城:还原日式美学,打造美好生活
2018/12/27 全球购物
工程地质勘察专业大学生求职信
2013/10/13 职场文书
放飞梦想演讲稿600字
2014/08/26 职场文书
先进班组事迹材料
2014/12/25 职场文书
技术负责人岗位职责
2015/02/10 职场文书
个人工作表现自我评价
2015/03/06 职场文书
2016圣诞节贺卡寄语
2015/12/07 职场文书
Redis命令处理过程源码解析
2022/02/12 Redis