深入探究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中的计算示例
Jun 28 Python
Python 读写文件和file对象的方法(推荐)
Sep 12 Python
发布你的Python模块详解
Sep 15 Python
使用Python脚本和ADB命令实现卸载App
Feb 10 Python
Python使用functools实现注解同步方法
Feb 06 Python
TensorFlow利用saver保存和提取参数的实例
Jul 26 Python
django query模块
Apr 20 Python
Tensorflow tensor 数学运算和逻辑运算方式
Jun 30 Python
Python读取多列数据以及用matplotlib制作图表方法实例
Sep 23 Python
Pytorch中TensorBoard及torchsummary的使用详解
May 12 Python
详解MindSpore自定义模型损失函数
Jun 30 Python
分享Python异步爬取知乎热榜
Apr 12 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
一个自定义位数的php多用户计数器代码
2007/03/11 PHP
PHP 手机归属地查询 api
2010/02/08 PHP
获取PHP警告错误信息的解决方法
2013/06/03 PHP
PHP使用strstr()函数获取指定字符串后所有字符的方法
2016/01/07 PHP
PHP PDOStatement::errorCode讲解
2019/01/31 PHP
分享27个jQuery 表单插件集合推荐
2011/04/25 Javascript
JS焦点图切换,上下翻转
2011/05/12 Javascript
javascript面向对象特性代码实例
2014/06/12 Javascript
JS解析XML文件和XML字符串详解
2015/04/17 Javascript
vue-router+vuex addRoutes实现路由动态加载及菜单动态加载
2017/09/28 Javascript
Angular4实现图片上传预览路径不安全的问题解决
2017/12/25 Javascript
微信小程序App生命周期详解
2018/01/31 Javascript
vue-router相关基础知识及工作原理
2018/03/16 Javascript
react配合antd组件实现的管理系统示例代码
2018/04/24 Javascript
微信小程序用户位置权限的获取方法(拒绝后提醒)
2018/11/15 Javascript
js 将线性数据转为树形的示例代码
2019/05/28 Javascript
vue resource发送请求的几种方式
2019/09/30 Javascript
小程序如何写动态标签的实现方法
2020/02/05 Javascript
JavaScript实现打字游戏
2021/02/19 Javascript
python+selenium打印当前页面的titl和url方法
2018/06/22 Python
Python re 模块findall() 函数返回值展现方式解析
2019/08/09 Python
python字典的遍历3种方法详解
2019/08/10 Python
TensorFlow MNIST手写数据集的实现方法
2020/02/05 Python
keras训练曲线,混淆矩阵,CNN层输出可视化实例
2020/06/15 Python
django跳转页面传参的实现
2020/09/17 Python
一款纯css3实现的圆形旋转分享按钮旋转角度可自己调整
2014/09/02 HTML / CSS
amazeui树节点自动展开折叠面板并选中第一个树节点的实现
2020/08/24 HTML / CSS
澳洲国民品牌乡村路折扣店:Country Road & Trenery Outlet
2018/04/19 全球购物
财务管理专业推荐信
2013/11/19 职场文书
艺术设计专业个人求职信范文
2013/12/11 职场文书
儿媳婚宴答谢词
2014/01/14 职场文书
初中中等生评语
2014/12/29 职场文书
2016年学校禁毒宣传活动工作总结
2016/04/05 职场文书
适合青年人白手起家的创业项目分享
2019/08/16 职场文书
浅谈CSS不规则边框的生成方案
2021/05/25 HTML / CSS
python 安全地删除列表元素的方法
2022/03/16 Python