淘宝、天猫、京东等电商网站的出现,让我们足不出户就能购物。在这些网站中,都有一个“购物车”的功能。当我们在不同商品页面将商品加入购物车,然后关闭浏览器。等下次浏览该网站时,我们会依然发现购物车的商品还在。这是怎么实现的了?类似这种场景,一般都是采用 Cookie + Session 方式来实现。
1 Cookie 机制
HTTP 协议是无状态的。所以服务器无法根据 HTTP 协议来辨别多个 HTTP 请求来自哪个用户。在实际场景中,服务器经常需要追踪客户端的状态。为了解决这个问题, Cookie 技术应运而生。
cookie 一开始是服务器产生的一段随机字符串。它的主要内容包括:名字,值,过期时间,路径与域等信息。然后服务器将其发送给客户端。在后续的请求中,cookie 会附在请求资源的 HTTP 请求头上,发送给服务器。
2 Session 机制
如果不涉及用户登录等敏感信息时,Cookie 能够满足大部分的场景需求。而客户端(如浏览器)会将 Cookie 是保存在硬盘中。如果用户登录敏感信息保存到 cookie 中,会存在安全性问题。因为当 HTTP 请求被黑客拦截,然后劫持 cookie 信息。黑客就可以凭借该 cookie 登录对应的网站。
Session 的出现很好地解决的这个问题。Session 机制是一个服务器端的机制。它会将信息保存服务器端,跟客户端通信只需要一个随机的字符串 session_id。如果客户端没有禁止 Cookie 功能,session_id 通常是保存在 Cookie中 的。如果 Cookie 被禁用,它则可能通过为 url 加上query string 来添加 session_id。
3 在 Django 中的应用
Django 为我们提供了一个通用的 Session 框架。使用 Django 2.X 版本创建新项目的时,Django 默认会帮我们启用该功能。
Django 默认 Session 数据保存到数据库中,可以在 settings.py 中看到配置信息项目。
INSTALLED_APPS = [
# 启用 sessions 应用
'django.contrib.sessions',
]
MIDDLEWARE = [
# 启用 Session 中间层
'django.contrib.sessions.middleware.SessionMiddleware',
]
然后我们在将自带组件的模型同步到数据库中。如果你还不熟悉这块内容,可以阅读《Django 学习笔记之模型(上)》这篇文章。我们之后会看到数据库中有个 django_session
表:
除了上述的基于数据库的会话,Django 还提供另外三种方法:
1)保存到缓存中
如果你的场景需要快速存储会话,可以选择该方案。使用之前,需要配置下 Django 的缓存框架。在 settings.py 中增加 SESSION_ENGINE 配置。
这其中也是有两种保存数据的方案,具体配置如下:
- 方案一
SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
这种配置方案 Django 只是简单保存会话。同时,这种方案持久性不好。因为当缓存数据存满时将清除部分数据,或者遇到缓存服务器重启时数据将丢失。
- 方案二
SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'
这种方案既保证快速存储会话数据,又保证数据持久性。因为该使用方案, Session 在保存到缓存的同时还会被保存到数据库中,当 Django 在缓存中找不到Session 时,会从数据库中找到。因此,这种方案的性能开销会比方案一大。
如果我们在工程中同时配置了数据库会话和缓存会话,Django 默认优秀选择缓存会话。
2)保存到文件中
这种方案是保存数据到本地磁盘中。因为磁盘的 I/O 瓶颈问题,导致这种方案存储数据效率不是很高。如果要使用这种方案,在 settings.py 中增加 SESSION_ENGINE 配置。具体配置如下:
SESSION_ENGINE = 'django.contrib.sessions.backends.file'
# 可选配置
SESSION_FILE_PATH = '/monkey/www/'
SESSION_FILE_PATH 默认使用 tempfile.gettempdir() 方法的返回值,就像 /tmp目录。如果你想更新文件的保存路径,可以手动指定。另外需确保你的文件存储目录,以及 Web 服务器对该目录具有读写权限。
3)保存到 cookie 中
这种方案将数据保存到 cookie 中。这种方案适用于对数据保密性不严格的场景。如果要使用这种方案,在 settings.py 中增加 SESSION_ENGINE 配置。具体配置如下:
SESSION_ENGINE = 'jango.contrib.sessions.backends.signed_cookies'
# 建议配置,阻止 javascript 对会话数据的访问,提高安全性。
SESSION_COOKIE_HTTPONLY= True
往前 Django 学习笔记文章
Django 学习笔记之环境搭建
Django 学习笔记之初始
Django 学习笔记之视图与URL配置
Django 学习笔记之模板
Django 学习笔记之模型(上)
Django 学习笔记之模型(下)
Django 学习笔记之后台管理
Django 学习笔记之模型表单
Django 学习笔记之使用旧数据库
Django 实战1:搭建属于自己社工查询系统(上)
Django 实战1:搭建属于自己社工查询系统(下)
Django 学习笔记之模型高级用法(上)
Django 学习笔记之模型高级用法(下)
Django 实现分页功能
本文原创发布于微信公众号「极客猴」,欢迎关注第一时间获取更多原创分享