深入探究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自定义函数的创建、调用和函数的参数详解
Mar 11 Python
解决Python中字符串和数字拼接报错的方法
Oct 23 Python
Python批量查询域名是否被注册过
Jun 21 Python
对Python 检查文件名是否规范的实例详解
Jun 10 Python
Centos7 下安装最新的python3.8
Oct 28 Python
Python FTP文件定时自动下载实现过程解析
Nov 12 Python
Pytorch高阶OP操作where,gather原理
Apr 30 Python
Python新手学习标准库模块命名
May 29 Python
keras Lambda自定义层实现数据的切片方式,Lambda传参数
Jun 11 Python
Python 远程开关机的方法
Nov 18 Python
Python基于mediainfo批量重命名图片文件
Dec 29 Python
python3 hdf5文件 遍历代码
May 19 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 curl获取网页内容(IPV6下超时)的解决办法
2013/07/16 PHP
php中文字符串截取多种方法汇总
2016/10/06 PHP
PHP getDocNamespaces()函数讲解
2019/02/03 PHP
一些不错的js函数ajax
2008/08/20 Javascript
JQuery在光标位置插入内容的实现代码
2010/06/18 Javascript
js中document.getElementByid、document.all和document.layers区分介绍
2011/12/08 Javascript
JS获取鼠标坐标的实例方法
2013/07/18 Javascript
javascript日期计算实例分析
2015/06/29 Javascript
JS实现双击内容变为可编辑状态
2017/03/03 Javascript
redux-saga 初识和使用
2018/03/10 Javascript
Nodejs让异步变成同步的方法
2019/03/02 NodeJs
vue中input的v-model清空操作
2019/09/06 Javascript
构建Vue大型应用的10个最佳实践(小结)
2019/11/07 Javascript
小程序websocket心跳库(websocket-heartbeat-miniprogram)
2020/02/23 Javascript
Vue 集成 PDF.js 实现 PDF 预览和添加水印的步骤
2021/01/22 Vue.js
Javascript实现打鼓效果
2021/01/29 Javascript
[02:04]2014DOTA2国际邀请赛 DK一个时代的落幕
2014/07/21 DOTA
初步介绍Python中的pydoc模块和distutils模块
2015/04/13 Python
在Python的Flask框架下收发电子邮件的教程
2015/04/21 Python
Python用Bottle轻量级框架进行Web开发
2016/06/08 Python
python使用socket创建tcp服务器和客户端
2018/04/12 Python
Python基础之文件读取的讲解
2019/02/16 Python
Python地图绘制实操详解
2019/03/04 Python
Pandas之Fillna填充缺失数据的方法
2019/06/25 Python
python利用dlib获取人脸的68个landmark
2019/11/27 Python
Django实现前台上传并显示图片功能
2020/05/29 Python
通过cmd进入python的步骤
2020/06/16 Python
印度最好的在线药品订购网站:PharmEasy
2018/11/30 全球购物
留学推荐信怎么写
2014/01/25 职场文书
2014年道德讲堂实施方案
2014/03/05 职场文书
校园文化标语
2014/06/18 职场文书
沙滩主题婚礼活动策划方案
2014/09/15 职场文书
房屋买卖协议样本
2014/11/16 职场文书
2016大学先进团支部事迹材料
2016/03/01 职场文书
Spring this调用当前类方法无法拦截的示例代码
2022/03/20 Java/Android
微信小程序APP页面的之间的相互传递参数以及自定义组件
2022/04/19 Javascript