深入探究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 20 Python
Python网络编程中urllib2模块的用法总结
Jul 12 Python
Python中使用haystack实现django全文检索搜索引擎功能
Aug 26 Python
Numpy中转置transpose、T和swapaxes的实例讲解
Apr 17 Python
Python设计模式之简单工厂模式实例详解
Jan 22 Python
Python 抓取微信公众号账号信息的方法
Jun 14 Python
python字符串分割及字符串的一些常规方法
Jul 24 Python
Python 添加文件注释和函数注释操作
Aug 09 Python
Python hashlib和hmac模块使用方法解析
Dec 08 Python
Python中读取文件名中的数字的实例详解
Dec 25 Python
FP-growth算法发现频繁项集——发现频繁项集
Jun 24 Python
Python爬取用户观影数据并分析用户与电影之间的隐藏信息!
Jun 29 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
Wordpress 相册插件 NextGEN-Gallery 添加目录将中文转为拼音的解决办法
2010/12/29 PHP
dhtmlxTree目录树增加右键菜单以及拖拽排序的实现方法
2013/04/26 PHP
PHP 过滤页面中的BOM(实现代码)
2013/06/29 PHP
PHP中防止SQL注入方法详解
2014/12/25 PHP
phpcms手机内容页面添加上一篇和下一篇
2015/06/05 PHP
效率高的Javscript字符串替换函数的benchmark
2008/08/02 Javascript
20款非常优秀的 jQuery 工具提示插件 推荐
2012/07/15 Javascript
浅谈jquery回调函数callback的使用
2015/01/30 Javascript
基于JavaScript实现动态创建表格和增加表格行数
2015/12/20 Javascript
javascript生成img标签的3种实现方法(对象、方法、html)
2015/12/25 Javascript
js实现可旋转的立方体模型
2016/10/16 Javascript
用js制作淘宝放大镜效果
2020/10/28 Javascript
jquery实现左右滑动式轮播图
2017/03/02 Javascript
使用wxapp-img-loader自定义组件实现微信小程序图片预加载功能
2018/10/18 Javascript
layui使用templet格式化表格数据的方法
2019/09/16 Javascript
python sys模块sys.path使用方法示例
2013/12/04 Python
Python基于smtplib实现异步发送邮件服务
2015/05/28 Python
Go语言基于Socket编写服务器端与客户端通信的实例
2016/02/19 Python
浅谈Python NLP入门教程
2017/12/25 Python
Python实现的字典值比较功能示例
2018/01/08 Python
python 不以科学计数法输出的方法
2018/07/16 Python
Python实现微信自动好友验证,自动回复,发送群聊链接方法
2019/02/21 Python
OpenCV-Python 摄像头实时检测人脸代码实例
2019/04/30 Python
python如何实现代码检查
2019/06/28 Python
Django中ORM的基本使用教程
2020/12/22 Python
Python操作PostgreSql数据库的方法(基本的增删改查)
2020/12/29 Python
HTML5实现Notification API桌面通知功能
2016/03/02 HTML / CSS
iframe与window.onload如何使用详解
2020/05/07 HTML / CSS
印度网上购物首选目的地:Flipkart
2016/08/01 全球购物
瑞典最大的儿童用品网上商店:pinkorblue.se
2021/03/09 全球购物
霸气押韵的班级口号
2014/06/09 职场文书
个人年终总结开头
2015/03/06 职场文书
当你焦虑迷茫时,请读读这6句话
2019/07/24 职场文书
导游词之西湖雷峰塔
2019/09/18 职场文书
Mysql数据库中datetime、bigint、timestamp来表示时间选择,谁来存储时间效率最高
2021/08/23 MySQL
vue特效之翻牌动画
2022/04/20 Vue.js