很多刚开始做 Web 项目的同学,第一次接触登录鉴权时都会有点懵:

Cookie 是什么?
Session 是什么?
SessionId 又是什么?
Token 和 JWT 是一回事吗?
JWT 已经有过期时间了,为什么有些项目还要用 Redis?
退出登录时,JWT 不是也能设置 token 失效吗?
SessionStorage 和 Session 有关系吗?

这些概念看起来很多,其实它们都围绕同一个问题:

服务器怎么知道当前请求的人已经登录过?

这篇文章用小白能听懂的方式,把登录鉴权里最常见的几个概念串起来。


目录


一、为什么需要登录鉴权?

假设 Lea 登录一个网站后,服务器需要知道几件事:

1. Lea 已经登录过了吗?
2. Lea 是哪个用户?
3. Lea 有没有权限访问这个接口?
4. Lea 的登录状态有没有过期?

问题是:

HTTP 本身是无状态的。

也就是说,服务器默认不会自动记得:

上一次请求的人是谁
这个人有没有登录过
这个人有没有权限

所以系统需要设计一套机制,让服务器能判断用户是否已经登录。

这就引出了这些概念:

Cookie
Session
SessionId
Token
JWT
Redis
SessionStorage

二、先记住一句话

可以先粗略这样理解:

名称 简单理解
Cookie 浏览器自动携带的小纸条
Session 服务器里的登录档案
SessionId 找到登录档案的编号
Token 登录后的通行证
JWT 一种自带信息和过期时间的特殊 Token
Redis 服务器端常用来存登录状态、黑名单、刷新令牌或额外失效控制的地方
SessionStorage 浏览器里临时保存 key-value 的小仓库

核心问题永远只有一个:

服务器怎么判断这个用户已经登录?


三、Cookie 是什么?

Cookie 是浏览器本地保存的一小段数据。

它最大的特点是:

浏览器会自动把 Cookie 带给对应网站的服务器。

比如浏览器里有:

SESSIONID=abc123

之后请求接口时,浏览器可能会自动带上:

GET /api/user/info
Cookie: SESSIONID=abc123

所以 Cookie 经常用来保存登录相关的编号,比如 sessionId

简单理解:

Cookie = 浏览器保存并自动携带的小纸条

四、Session 是什么?

这里说的 Session,不是浏览器 F12 里的 SessionStorage。

这里的 Session 指的是:

服务器端保存的一份登录状态。

可以理解为:

Session = 服务器给用户开的一份登录档案

比如 Lea 登录成功后,服务器在 Redis 里存一条记录:

key: session:abc123
value: userId=10001, username=Lea, role=user
expire: 30 minutes

这条记录表示:

Lea 已经登录
用户 ID 是 10001
角色是 user
30 分钟后过期

注意:

Session 是存在服务器端的,不是存在浏览器里的。


五、Session 和 SessionId 的区别

这两个概念很容易混在一起。

名称 在哪里 是什么
Session 服务器 / Redis 里 真正的登录信息
SessionId 浏览器 Cookie 里 找到 Session 的编号

比如 Redis 里有:

key: session:abc123
value: userId=10001, username=Lea, role=user
expire: 30 minutes

浏览器 Cookie 里只有:

SESSIONID=abc123

所以:

Session = 服务器里的登录档案
SessionId = 浏览器手里的档案编号
Cookie = 浏览器保存并自动携带 SessionId 的地方
Redis = 常见的 Session 存储位置

六、Session 登录流程

以 Lea 登录为例:

1. Lea 输入账号密码
2. 后端去数据库校验账号密码是否正确
3. 校验成功后,后端生成一个 sessionId,比如 abc123
4. 后端把 Lea 的登录信息存到 Redis 里
5. Redis 设置过期时间,比如 30 分钟
6. 后端把 sessionId 返回给浏览器
7. 浏览器把 sessionId 存到 Cookie 里
8. 之后每次请求,浏览器自动带上 Cookie
9. 后端拿到 sessionId,去 Redis 查 Session
10. 查得到 = 已登录
11. 查不到 = 未登录 / 登录过期

请求时大概是这样:

GET /api/user/info
Cookie: SESSIONID=abc123

后端收到后:

拿到 abc123
↓
去 Redis 查 session:abc123
↓
查得到,说明 Lea 登录还有效
查不到,说明 Lea 未登录或登录已过期

七、Token 是什么?

Token 也是一种登录凭证。

可以理解为:

Token = 用户登录成功后拿到的一张通行证

登录成功后,服务器返回 token:

{
  "token": "abcdefg123456"
}

前端可能把 token 存在:

SessionStorage
LocalStorage
内存变量
Cookie

之后请求接口时,前端通常会把 token 放到请求头里:

GET /api/user/info
Authorization: Bearer abcdefg123456

重点是:

前端只是保存和携带 token,真正判断 token 是否有效的是后端。


八、有 Token 还需要 Session 吗?

不一定。

Token 和 Session 都是为了解决:

服务器怎么知道用户已经登录了?

但它们是两种不同方案,不是一定要同时存在。

常见有三种情况:

1. 只用 Session
2. 只用 Token
3. Token + Redis 一起用

1. 只用 Session

传统后台系统比较常见。

浏览器保存 sessionId
后端 / Redis 保存 Session 登录信息
每次请求,后端拿 sessionId 去 Redis 查

查得到,就是已登录。

查不到,就是未登录或登录过期。

2. 只用 Token

前后端分离项目、App、小程序比较常见。

前端保存 token
每次请求带 token
后端校验 token

如果 token 校验通过,就认为用户已登录。

这种模式下,不一定需要 Session。


九、JWT 是什么?

JWT 是一种特殊格式的 Token。

它通常长这样:

xxxxx.yyyyy.zzzzz

三段分别是:

Header.Payload.Signature

可以粗略理解为:

Header = 说明 token 类型和算法
Payload = 存一些信息,比如 userId、用户名、过期时间
Signature = 签名,用来防止 token 被篡改

JWT 的 Payload 里可能有:

{
  "userId": 10001,
  "username": "Lea",
  "role": "user",
  "exp": 1719999999
}

这里的 exp 就是过期时间。

所以可以这样理解:

JWT = 自带身份信息、签名和过期时间的特殊 Token

但是要注意:

不是前端看见 exp 就算过期,而是后端校验 JWT 时发现 exp 过期了,才认为它无效。

还要特别注意:

JWT 的 exp 解决的是“到期自动失效”,不是“用户点击退出后立刻失效”。


十、JWT 为什么不一定要存 Redis?

因为 JWT 自己可以带信息:

userId
username
role
exp 过期时间
签名

后端收到 JWT 后,可以直接:

1. 校验签名是否正确
2. 校验 exp 是否过期
3. 解析出 userId
4. 判断用户身份

如果都通过,就认为用户已登录。

这种方式叫:

无状态登录

意思是:

服务器不一定需要在 Redis 里保存这个 token。


十一、为什么有些项目 JWT 还要配 Redis?

因为纯 JWT 有一个问题:

只要 JWT 没到过期时间,它理论上就还能用。

比如 JWT 有效期是 2 小时。

Lea 点击退出登录后,前端把 token 删除了。

但是如果这个 token 之前被别人复制走了,而且还没过期,它理论上仍然可能继续请求接口。

也就是说:

纯 JWT 可以不存 Redis。
但纯 JWT 默认只能靠 exp 到期失效。

如果要做到:

用户点击退出登录后
后端立刻不再认可这个还没过期的 JWT

后端就需要有某种额外状态。

这个额外状态不一定非得是 Redis,也可以是数据库、内存缓存等。

只是 Redis 速度快、支持过期时间,所以实际项目里很常用。

很多项目会用 Redis 做这些控制:

1. Redis 存 token 黑名单
2. Redis 存 refresh token
3. Redis 存用户在线状态
4. Redis 存当前有效 token 版本号
5. 退出登录时,把 token 加入黑名单
6. 踢人下线时,删除 Redis 里的登录状态

所以实际项目里经常会出现:

JWT + Redis

可以这样理解:

JWT 负责证明用户身份
Redis 负责额外控制登录状态

十二、Token + Redis 是什么?

这种方式和 Session 思想有点像。

登录成功后:

1. 后端生成 token
2. 后端把 token 返回给前端
3. 前端保存 token
4. 后端也在 Redis 里保存一份 token 或登录状态
5. Redis 设置过期时间,比如 30 分钟

Redis 里可能是:

key: login:token:abcdefg123456
value: userId=10001, username=Lea, role=user
expire: 30 minutes

之后请求接口时:

GET /api/user/info
Authorization: Bearer abcdefg123456

后端收到后:

1. 校验 token 格式 / 签名
2. 去 Redis 查这个 token 是否还有效
3. Redis 有 = 已登录
4. Redis 没有 = 未登录 / 已过期 / 被踢下线

这种方式方便实现:

1. 退出登录后立即让服务端不再认可这个 token
2. 踢人下线
3. 限制单端登录
4. 控制服务端认可的有效期
5. 统计在线用户

十三、SessionStorage 是什么?

SessionStorage 是浏览器 F12 里看到的本地存储。

它和后端 Session 不是一回事。

SessionStorage 可以理解为:

浏览器当前标签页里的临时小仓库

里面是 key-value 形式:

key: token
value: abcdefg123456

前端代码可以把 token 存进去:

sessionStorage.setItem("token", "abcdefg123456");

也可以取出来放到请求头里:

const token = sessionStorage.getItem("token");

axios.get("/api/user/info", {
  headers: {
    Authorization: "Bearer " + token
  }
});

重点:

SessionStorage 只是保存 token,不负责判断登录是否有效。

真正判断的是后端。


十四、常见概念对比表

名称 在哪里 作用
Cookie 浏览器本地 保存少量数据,会自动随请求发送
Session 服务器 / Redis 保存用户登录状态
SessionId 浏览器 Cookie 里 找到服务器端 Session 的编号
Token 前端和后端之间传递 登录凭证,证明“我是谁”
JWT 一种特殊 Token 自带用户信息、签名、过期时间
Redis 服务器端 保存登录状态、token、黑名单、刷新令牌等
SessionStorage 浏览器 F12 里 前端临时保存 key-value 数据

最简单的记忆方式:

Session = 服务器里的登录档案
SessionId = 浏览器手里的档案编号
Cookie = 自动携带 SessionId 的地方
Token = 用户登录后的通行证
JWT = 自带身份信息和过期时间的特殊 Token
Redis = 服务器端常用来存登录状态、黑名单、刷新令牌或额外失效控制的地方
SessionStorage = 浏览器临时保存 token 的小仓库

十五、总结

登录鉴权可以这样串起来:

用户输入账号密码
↓
后端校验账号密码
↓
校验成功后,后端生成登录凭证
↓
这个凭证可能是 sessionId,也可能是 token
↓
前端保存凭证
↓
之后每次请求都带上凭证
↓
后端校验凭证
↓
校验通过 = 已登录
校验失败 = 未登录 / 登录过期

最后记住一句话:

登录不是浏览器自己说了算,而是浏览器带凭证,服务器来判断这个凭证是否有效。

关于 JWT 和 Redis,也可以记住这句话:

纯 JWT 可以不需要 Redis;但如果要做到退出登录后立即失效、踢人下线、限制单端登录,就需要 Redis 或数据库这类服务端状态。

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐