深入探究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 client使用http post 到server端的代码
Feb 10 Python
跟老齐学Python之使用Python查询更新数据库
Nov 25 Python
利用Python爬取可用的代理IP
Aug 18 Python
Python多层装饰器用法实例分析
Feb 09 Python
Flask框架使用DBUtils模块连接数据库操作示例
Jul 20 Python
python实现flappy bird游戏
Dec 24 Python
解决.ui文件生成的.py文件运行不出现界面的方法
Jun 19 Python
Python分割训练集和测试集的方法示例
Sep 19 Python
Python 去除字符串中指定字符串
Mar 05 Python
Python如何输出百分比
Jul 31 Python
如何使用python自带IDLE的几种方法
Oct 10 Python
python实现简单猜单词游戏
Dec 24 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
PHP5各个版本的新功能和新特性总结
2014/03/16 PHP
JavaScript实现动态增加文件域表单
2009/02/12 Javascript
非常有用的40款jQuery 插件推荐(系列二)
2011/12/25 Javascript
用js实现table单元格高宽调整,兼容合并单元格(兼容IE6、7、8、FF)实例
2013/06/25 Javascript
Extjs NumberField后面加单位实现思路
2013/07/30 Javascript
javascript事件函数中获得事件源的两种不错方法
2014/03/17 Javascript
javascript字符串替换函数如何一次性全部替换掉
2015/10/30 Javascript
JavaScript+html5 canvas制作的百花齐放效果完整实例
2016/01/26 Javascript
ECHO.js 纯javascript轻量级延迟加载的实例代码
2016/05/24 Javascript
js数组操作方法总结(必看篇)
2016/11/22 Javascript
火狐和ie下获取javascript 获取event的方法(推荐)
2016/11/26 Javascript
vue mixins组件复用的几种方式(小结)
2017/09/06 Javascript
详解Vue依赖收集引发的问题
2019/04/22 Javascript
NodeJs crypto加密制作token的实现代码
2019/11/15 NodeJs
mapboxgl实现带箭头轨迹线的代码
2021/01/04 Javascript
[01:18]一目了然!DOTA2DotA快捷操作对比第一弹
2014/07/01 DOTA
python通过线程实现定时器timer的方法
2015/03/16 Python
详细介绍Python中的偏函数
2015/04/27 Python
pycharm设置鼠标悬停查看方法设置
2019/07/29 Python
Python基于numpy模块实现回归预测
2020/05/14 Python
利用CSS3的border-radius绘制太极及爱心图案示例
2016/05/17 HTML / CSS
台湾前三大B2C购物网站:MOMO购物网
2017/04/27 全球购物
英国门把手公司:Door Handle Company
2019/05/12 全球购物
Liu Jo西班牙官网:意大利服装品牌
2019/09/11 全球购物
Mamaearth官方网站:印度母婴护理产品公司
2019/10/06 全球购物
商务主管岗位职责
2013/12/08 职场文书
物流管理专业推荐信
2014/09/06 职场文书
县政府领导班子四风问题对照检查材料思想汇报
2014/09/26 职场文书
2014年社区妇联工作总结
2014/12/02 职场文书
放弃继承权公证书
2015/01/23 职场文书
司机个人年终总结
2015/03/03 职场文书
博士导师推荐信
2015/03/25 职场文书
出纳岗位职责范本
2015/03/31 职场文书
公司年会晚会开幕词
2019/04/02 职场文书
HashMap实现保存两个key相同的数据
2021/06/30 Java/Android
python超详细实现完整学生成绩管理系统
2022/03/17 Python