状态保持
- 目前我是用的一共有两种状态保持机制。
- (1)session机制的
- (2)JWT,json web token 机制的
(我们主要介绍第一种session机制,后面一种在后续讲解 django drf 做后台管理时讲)
什么是Cookie?
简单的说,就是Cookie是存储在浏览器中的一段纯文本信息,在网站请求中用来 辨别用户身份、进行session跟踪而储存在用户本地终端上的数据(通常经过加密)。
- 特点:
-
Cookie以键值对的格式进行信息的存储。
-
Cookie基于域名安全,不同的域名之间,不能互相访问。如访问www.baidu.com时向浏览器中写了Cookie信息,使用同一浏览器访问www.youkuaiyun.com时,无法访问到www.baidu.com写的Cookie信息
-
典型应用:记住用户名,网站的广告推送。
-
缺点:安全性较差。因为数据存储在用户本地当中
-
什么是session?
- 是一种记录客户状态的机制。用于存储敏感,重要的信息(如用户名、余额、等级、验证码等信息),存储位置是在服务器端
- 特点:
-
依赖于cookie,在使用Session后,会在Cookie中存储一个sessionid的数据,每次请求时浏览器都会将这个数据发给服务器,服务器在接收到sessionid后,会根据这个值找出这个请求者的Session。
-
数据更加安全
-
存储Session时,键与Cookie中的sessionid相同,值是开发人员设置的键值对信息,进行了base64编码,过期时间由开发人员设置。
-
存储形式:
- session在redis(redis作为存储)中的存储形式为: string类型
- 格式: key:value
- key 就是sessionid
- value 是一个字符串形式的字典数据:‘{‘用户名’:‘密码’}’
-
看到这里,我们就大致明白了上节中的 login() 函数的作用:
- 就是做状态保持, login()使用Django的session框架来将用户的ID保存在session中。
- 并在用户本地中存储一个 sessionid。
- 字符串类型是Redis中最为基础的数据存储类型,它在Redis中是二进制安全的,可以存储任何形式的数据。
- 这一点我也不能理解,为啥显示的这个值,无法正确的用base64解密? 之后我又尝试再django里打印这个值
我企图用django 打印它, 结果 得到的是 字节, 但是 也不能 decode()?? 那django内部是怎么使用的这个 东西呀?解码也解不了? - 之后我又手动添加了一个值
这就完成了,用户每次访问网站,都能判断是否 用户登录(完成状态保持)。
可以正常显示!
- 这不禁让我想是谁干的?首先想到的是 做登录状态保持的 login() 函数
- 但是观察可以知道,这个函数不过是调用了 啥session框架来实现。
- 所以:最终我的猜想是,
下面具体说下session机制的流程 django-redis模块的 对session的加密处理了, 因为login()函数只是做 调用, django-redis正式用来完成保存 session的 session框架吧?
- 另外提供官方的文档:如何使用会话
其中介绍了其他的session方法。 默认的时使用
数据库作为session,可以阅读下文档,了解下。
(这是我的理解~ 欢迎大家再评论区讨论!指出你的观点,或者是我的错误理解!)
session机制
图示:
步骤分解
- (1) 首先 浏览器向 django发送POST请求,携带用户名还有密码
- (2)验证成功,调用login()函数,将 session 写入到配置好的 redis当中。
- (3)写入一个sessionid 到cookie当中,其中键就是sessionid, 值就是 在session当中存储的键
- (4) 下次,也就是下次,访问时,就会携带这个 cookie,后端便会提取sessionid,接着查询redis数据库,获取sessionid对应的值
- (5) 当查询得到值,说明用户是登录的。查询不到说明用户登录状态已经过期! 表示退出登录了。
session机制的缺陷:
- (1)内存紧张: 要知道,redis的数据是存储到 内存当中的。当用户数目庞大的时候,每一个用户都要在 redis中存储一个session数据,这时就会造成服务器的存储压力了。 解决办法:需要去购买硬件,扩充redis的存储空间了。
- (2)扩展性问题: 扩展服务器,当搭建服务集群时,我们可以有很多django服务,每个django绑定不同的端口。 假设有两个django服务, 分别是 8000, 8001 端口。 当浏览器第一次访问 8000 服务的时候,设置了 session,这时数据是保存在8000的服务器上的,保持登陆,但当下次访问8001服务器时,就会找不到 对应的session,从而登陆状态验证失败。
- (3)csrf: 由于csrf(跨站请求伪造)是基于cookie来进行用户识别的,每当浏览器发送请求是自动携带cookie过去的,这样cookie就容易被截获!,用户就很容易受到 跨站请求伪造的 攻击。
这既是大致的 session机制。
可以采用 token机制解决上述问题,这个放到drf时再讲~
over!