深入探究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内置模块hashlib、hmac与uuid用法分析
Feb 12 Python
磁盘垃圾文件清理器python代码实现
Aug 24 Python
Python 使用PIL numpy 实现拼接图片的示例
May 08 Python
python3使用smtplib实现发送邮件功能
May 22 Python
tensorflow 获取模型所有参数总和数量的方法
Jun 14 Python
python实现一个简单的udp通信的示例代码
Feb 01 Python
使用PyQtGraph绘制精美的股票行情K线图的示例代码
Mar 14 Python
Python-while 计算100以内奇数和的方法
Jun 11 Python
Python 使用 PyMysql、DBUtils 创建连接池提升性能
Aug 14 Python
Python 寻找局部最高点的实现
Dec 05 Python
python文件编写好后如何实践
Jul 07 Python
Python如何把不同类型数据的json序列化
Apr 30 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 获取mysql数据库信息代码
2009/03/12 PHP
PHP通过文件保存和更新信息的方法分析
2019/09/12 PHP
学习JavaScript的最佳方法分享
2011/10/21 Javascript
js原生appendChild的bug解决心得分享
2013/07/01 Javascript
基于bootstrap3和jquery的分页插件
2015/07/31 Javascript
浅谈jQuery hover(over, out)事件函数
2016/12/03 Javascript
Jquery Easyui分割按钮组件SplitButton使用详解(17)
2016/12/18 Javascript
JS ES6多行字符串与连接字符串的表示方法
2017/04/26 Javascript
优雅的在React项目中使用Redux的方法
2018/11/10 Javascript
JavaScript基于遍历操作实现对象深拷贝功能示例
2019/03/05 Javascript
Element-ui中元素滚动时el-option超出元素区域的问题
2019/05/30 Javascript
详解Nuxt.js中使用Element-UI填坑
2019/09/06 Javascript
es6数组之扩展运算符操作实例分析
2020/04/25 Javascript
实例分析javascript中的异步
2020/06/02 Javascript
javascript实现评分功能
2020/06/24 Javascript
基于vue实现简易打地鼠游戏
2020/08/21 Javascript
微信小程序向Java后台传输参数的方法实现
2020/12/10 Javascript
python实现类的静态变量用法实例
2015/05/08 Python
Python导入模块时遇到的错误分析
2017/08/30 Python
Python jieba库用法及实例解析
2019/11/04 Python
Python谱减法语音降噪实例
2019/12/18 Python
基于Python测试程序是否有错误
2020/05/16 Python
详解基于python的图像Gabor变换及特征提取
2020/10/26 Python
python实现KNN近邻算法
2020/12/30 Python
Python3+Flask安装使用教程详解
2021/02/16 Python
日本一家专门经营各种箱包的大型网站:Traveler Store
2016/08/03 全球购物
英国天然抗衰老护肤品品牌:Nakin Skin Care
2019/04/16 全球购物
PatPat阿根廷:妈妈们的购物平台
2019/05/30 全球购物
PHP解析URL是哪个函数?怎么用?
2013/05/09 面试题
外贸采购员求职的自我评价
2013/11/26 职场文书
创先争优演讲稿
2014/09/15 职场文书
开除员工通知
2015/04/22 职场文书
《从现在开始》教学反思
2016/02/16 职场文书
如何使用Python实现一个简易的ORM模型
2021/05/12 Python
MySQL中日期型单行函数代码详解
2021/06/21 MySQL
SQLServer中exists和except用法介绍
2021/12/04 SQL Server