为什么需要 Session 和 Cookie
HTTP 请求是无状态的,这也就意味着浏览器收到一个请求,只知道要做什么任务,却不知道是任务发布者是谁。举个例子,用户想要查看购物车信息,如果没有 Session,服务器就无法知道查看哪个用户的购物车,也就无法给出准确的答复。
Cookie 的数据保存在客户端,可通过浏览器进行查看;Session 的数据保存在服务端,相比较而言更加安全,但如果数据过多,会影响运行效率。
Session 和 Cookie 的合作
当浏览器发出一个请求时,Session 随之建立,同时返回给浏览器的 response 中包含Set-Cookie 字段,通常该字段中会存在 session_id(sid)值。浏览器收到 response 后,会根据 Set-Cookie 字段设置 Cookie,下一次发送请求时,会自动携带该 Cookie。
这样,下一次服务端收到请求后,根据 sid 找到对应 Session,从而也就找到了该会话的一系列状态信息,例如当前登录的用户等等。这也就解决了 HTTP 请求无法保存状态信息的问题。如果遇到浏览器禁止 Cookie 的情况,也可将 sid 附加到 url 中。
以下为本人猜测内容,未经考证。在成熟 Web 框架,例如 SSM 中,Controller 收到请求会根据 sid 自动解析 Session,因此可以通过 request.getSession() 函数直接获取 Session 信息,而不需关心与 Session 相关的底层操作。
如何实现“保持登录状态”这一功能
有些时候,我们需要实现这样一个功能,即退出浏览器下次访问该网站时,可以自动登录,不需要重新输入用户名和密码。这一功能的实现就依赖于 Session 和 Cookie。
- 如果只靠 Session 来实现这一功能,可以延长 Session 的过期时间。一般来说,Session 会在会话结束时过期,即关闭浏览器后 Session 就会被销毁。而在 Django 中,Session 的默认过期时间是两周,如果用户不需要保存登录状态,则要将过期时间手动设为 0,这样关闭浏览器后用户就自动注销了。
- 如果使用 Cookie 来实现这一功能,则无需延长 Session 的过期时间。当用户登录成功后,浏览器返回的 Set-Cookie 中不仅要包含基本信息,还要包含登录用户的 ID、Token 或相关信息。这样用户下一次访问该网站时,Cookie 信息会随 request 发送到服务端,服务端通过解析 Cookie 得到用户 ID 和 Token。再将 ID 和 Token 与存储在数据库中的信息进行比对,如果相符,则在 Session 中设置当前登录的用户信息,并跳转到主页面;如果不符,跳转到系统的登录页面。