🔥前端小白必学:Cookie-Session如何保持登录状态?🔥

275 阅读5分钟

前言

当你在访问推特的时候,每点击一个新的板块就可以实现自动跳转,每访问到别的板块,你的登录状态仍然是在线,你有没有好奇过,他们是如何实现登录状态的持续的?我们都知道HTTP协议是无状态协议,这意味着 每次客户端向服务器发送请求时,服务器都不会保留任何关于之前请求的信息。 这种设计使得HTTP协议具有简单、高效的特点,但同时也带来了一个显著的问题:如何在一系列请求之间保持用户的会话状态?

这就要说到最早的存储机制——————“Cookie-Session” 了。

什么是 Cookie-Session ?

在之前的文章中我们提到:Cookie,小饼干,是存储在浏览器内的一小段数据,容量一般是4KB左右,能存储用户的一些关键信息,可以设置信息的过期时间,在每次浏览器发送请求时,都会自动携带。

而 Session,它是存储在服务器的数据,通过唯一的 Session ID 与客户端 Cookie 关联。它能够存储较大的数据(取决于服务器),也可以设置过期时间。

Cookie-Session 就是这样一种基于 Cookie 和服务器端存储的会话管理技术用于在 HTTP 无状态协议下保持用户登录状态和存储用户数据。 它是早期 Web 开发中最主流的身份验证方案之一,至今仍在许多传统系统中使用。

这个机制是如何运作的?

    1. 用户登录
    • 首先是用户登录,用户通过浏览器输入账号密码,发送给服务器进行校验。
    • 其次是服务器校验状态,校验通过后,从数据库拿到一些数据,并存储在session中(一般是你的个人信息,购物车的物品...),同时也会自身创建一些数据,通常是临时数据,其中包含sessionID
    • 然后,将sessionID利用Set-Cookie,将其保存在用户浏览器中
    1. 保持登录状态
    • 后续对于相关网站的请求,都自动携带cookie,也就把sessionID传递过去了
    • 服务器拿到sessionID,从数据库中进行搜索校验,确认用户身份,返回存储在session中的数据
    1. 退出登录
    • 浏览器退出,服务器删除Session,返回Set-Cookie使得Cookie失效。

登录时:

image.png

后来保持登录状态的时候,服务器就不会再向数据库发请求校验账号密码了,这个时候服务器会校验Cookie中所携带的SessionID,通过对应的SessionID返回对应的数据,比如Session中存储的数据可能是这样的:

{
  {
  "session_id": "a1b2c3d4e5f6",      // 会话唯一标识(由服务器生成)
  "user": {
    "user_id": 123,                  // 用户ID(数据库主键)
    "username": "alice",             // 用户名(用于显示)
    "email": "alice@example.com",    // 邮箱(脱敏处理)
    "role": "customer",              // 用户角色(如 admin/customer)
    "is_authenticated": true         // 是否已登录
  },
  "cart": [                          // 购物车商品列表
    {
      "product_id": 101,
      "name": "无线耳机",
      "price": 199.99,
      "quantity": 2
    },
    {
      "product_id": 205,
      "name": "手机壳",
      "price": 29.99,
      "quantity": 1
    }
  ],
  "preferences": {                   // 用户个性化设置
    "theme": "dark",                 // 主题(dark/light)
    "language": "zh-CN",             // 语言偏好
    "font_size": "medium"            // 字体大小
  },
  "security": {                      // 安全相关数据
    "ip_address": "192.168.1.100",   // 用户登录IP
    "user_agent": "Chrome/120.0",    // 浏览器标识
    "expires_at": "2024-05-20T23:59:59Z" // Session过期时间
  },
  "metadata": {                      // 其他元数据
    "created_at": "2024-05-18T10:00:00Z", // Session创建时间
    "last_activity": "2024-05-18T14:30:00Z" // 最后活跃时间
  }
}

}

只要服务器找到了你的session_id,它就能把这一大串数据返回给你。是不是很厉害!

7.gif

弊端

它是最早用来解决HTTP无状态协议导致无法保持用户状态的方法,但是它仍然存在一些弊端:

比如,它对服务器的存储压力是很大的,Session的数据通常会存在服务器的内存或数据库中,高并发的时候会导致一些问题,比如:当用户量激增的时候服务器内存成本高,每次查询Session信息的时候,会触发高频的 I/O ,可能会导致反应迟缓。

例:100万用户在线 → 100万条 Session 数据 → 每秒数万次 Redis 查询。

其次呢,拓展性有点差,在分布式集群或微服务架构中,Session共享困难,如果Session被存储在 A 服务器中,当用户请求被负载均衡到服务器 B 时无法识别。

以上这些不好的风险,就催生了Token的诞生,这个我们将留到下一期详细讲解~

总结

OK,这一期我们详细讲解了Cookie-Session的机制:

在我们首次登录时,向服务器发送请求,服务器根据我们传入的账号密码在数据库中校验身份,随后在数据库中拿到相关信息,存储在服务器中,并给浏览器返回一个session_id,之后每一次访问同源的网站都会只校验session_id,并返回相关信息。

最后在用户登出的时候,服务器会删除Session的数据,并设置浏览器的Cookie为空。