Session
session: 安全的 cookie
Cookie 在 Web 程序中发挥了很大的作用,其中最重要的功能是存储用户的认证信息。
我们先来看看基于浏览器的用户认证是如何实现的。当我们使用浏览器登录某个社交网站时,会在登录表单中过填写用户名和密码,单击登录按钮后,这会向服务器发送一个包含认证数据的请求。
服务器接收请求后会查找对应的账户,然后验证密码是否匹配,如果匹配,就在返回的响应中设置一个 cookie,比如 "login_user": greyli
响应被浏览器接收后,cookie 会被保存在浏览器中。
当用户再次向这个服务器发送请求时,根据请求附带的 Cookie 字段中的内容,服务器上的程序就可以判读用户的认证状态,并识别出用户
但是这会带来一个问题,在浏览器中手动添加和修改 Cookie 是很容易的事,仅仅通过浏览器插件就可以实现。
所以,如果直接把认证信息以明文的方式存储在 Cookie 里,那么恶意用户就可以通过伪造 cookie 的内容获得对网站的权限,冒用别人的账户。
为了避免这个问题,我们需要对敏感的 Cookie 内容进行加密。
附注:
在编程中,session 指用户会话(user session),又称为对话(dislogue),即服务器和客户端/浏览器之间或桌面程序和用户之间建立的交互活动。
在 Flask 中,session 对象用来加密 Cookie。默认情况下,它会把数据存储在浏览器上一个名为 session 的 cookie 里
- session 是另一种记录服务器和客户端会话状态的机制
- session 是基于 cookie 实现的,session 存储在服务器端,sessionID 会被存储到客户端的 cookie 中
session 认证流程:
- 用户第一次请求服务器的时候,服务器根据用户提交的相关信息,创建对应的 Session
- 请求返回时将此 Session 的唯一标识信息 SessionID 返回给浏览器
- 浏览器接收到服务器返回的 SessionID 信息后,会将此信息存入到 Cookie 中,同时 Cookie 记录此 SessionID 属于哪个域名
- 当用户二次访问服务器的时候,请求会自动判断域名下是否存在 Cookie 信息,如果存在自动将 Cookie 信息也发送给服务端,服务端会从 Cookie 中获取 SessionID,再根据 SessionID 查找对应的 Session 信息,如果没有找到说明用户没有登录或者登录失败,如果找到 Session 证明用户已经登录可执行后面操作
根据以上流程可知,SessionID 是连接 Cookie 和 Session 的一道桥梁,大部分系统也是根据此原理来验证用户登录状态
flask 实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
|
注意,为了使用 session,我们需要设置一个 secret key,以便 Flask 可以对 session 数据进行加密。在上述示例中,我们设置了一个名为 SECRET_KEY 的配置变量。还需要配置 SESSION_TYPE 以指定存储 session 数据的位置。
在上述示例中,我们将其设置为 filesystem,这将在文件系统上存储 session 数据。
Cookie 和 Session 的区别
- 安全性: Session 比 Cookie 安全,Session 是存储在服务器端的,Cookie 时存储在客户端的
- 存取值的类型不同,Cookie 只支持存字符串数据,想要设置其他类型的数据,需要将其转换成字符串,Session 可以存任意数据类型
- 有效期不同: Cookie 可设置为长时间保持,比如我们经常使用的默认登录功能,Session 一般失效时间较短,客户端关闭(默认情况下)或者 Session 超时都会失效
- 存储大小不同: 单个 Cookie 保存的数据不能超过 4K,Session 可存储数据远高于 Cookie,但是当访问量过多,会占用过多的服务器资源
session-cookie 认证存在的问题
- 当客户访问量增加,服务端需要存储大量的 session 会话,对服务端有很大考验
- 当服务端为集群时,用户登录其中一台服务器,会将 session 保存在该服务器的内存中,但是当用户访问其它服务器时。会无法访问
- 可以使用缓存服务器来保证共享
- 第三方缓存来保存 session
- 由于依赖 cookie,所以存在 CSRF 安全问题