深入探究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实现读取目录所有文件的文件名并保存到txt文件代码
Nov 22 Python
关于Python元祖,列表,字典,集合的比较
Jan 06 Python
CentOS7.3编译安装Python3.6.2的方法
Jan 22 Python
django解决跨域请求的问题
Nov 11 Python
搭建python django虚拟环境完整步骤详解
Jul 08 Python
Django框架model模型对象验证实现方法分析
Oct 02 Python
python基于event实现线程间通信控制
Jan 13 Python
Python的赋值、深拷贝与浅拷贝的区别详解
Feb 12 Python
浅谈django 重载str 方法
May 19 Python
python如何快速生成时间戳
Jul 21 Python
class类在python中获取金融数据的实例方法
Dec 10 Python
使用pandas模块实现数据的标准化操作
May 14 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使用Smarty的相关注意事项及访问变量的几种方式
2011/12/08 PHP
如何在smarty中增加类似foreach的功能自动加载数据
2013/06/26 PHP
php去除字符串换行符示例分享
2014/02/13 PHP
PHP积分兑换接口实例
2015/02/09 PHP
php简单分页类实现方法
2015/02/26 PHP
yii通过小物件生成view的方法
2016/10/08 PHP
php tpl模板引擎定义与使用示例
2019/08/09 PHP
php array 转json及java 转换 json数据格式操作示例
2019/11/13 PHP
Thinkphp 框架扩展之Widget扩展实现方法分析
2020/04/23 PHP
Ucren Virtual Desktop V2.0
2006/11/07 Javascript
jQuery选择头像并实时显示的代码
2010/06/27 Javascript
Jjcarousellite 实现图片列表滚动的简单实例
2013/11/29 Javascript
js点击文本框弹出可选择的checkbox复选框
2016/02/03 Javascript
深入解析JavaScript中的arguments对象
2016/06/12 Javascript
angular.js+node.js实现下载图片处理详解
2017/03/31 Javascript
原生JS实现自定义滚动条效果
2020/10/27 Javascript
微信小程序wx.uploadfile 本地文件转base64的实现代码
2018/06/28 Javascript
微信小程序实现漂亮的弹窗效果
2020/05/26 Javascript
详解处理bootstrap4不支持远程静态框问题
2018/07/20 Javascript
React中如何引入Angular组件详解
2018/08/09 Javascript
vue生命周期实例小结
2018/08/15 Javascript
微信小程序向Java后台传输参数的方法实现
2020/12/10 Javascript
python保存字符串到文件的方法
2015/07/01 Python
Python常见格式化字符串方法小结【百分号与format方法】
2016/09/18 Python
Python 获得13位unix时间戳的方法
2017/10/20 Python
python3爬虫之设计签名小程序
2018/06/19 Python
Python基于requests库爬取网站信息
2020/03/02 Python
python的launcher用法知识点总结
2020/08/07 Python
python 如何使用find和find_all爬虫、找文本的实现
2020/10/16 Python
css3简单练习实现遨游浏览器logo的绘制
2013/01/30 HTML / CSS
HTML5+CSS3绘制锯齿状的矩形
2016/03/01 HTML / CSS
基于HTML5 的人脸识别活体认证的实现方法
2016/06/22 HTML / CSS
民主评议党员总结
2014/10/20 职场文书
新员工考核评语
2014/12/31 职场文书
工程部经理岗位职责
2015/02/02 职场文书
公司搬迁通知
2015/04/20 职场文书