ctx.session.xxx = xxx:不是直接存储在前端的 Session Storage 或 Local Storage 中,而是存储在服务端(Koa)管理的会话中,通常基于 Cookie 实现。ctx.cookies.set('xxx', 'xxx'):是设置 Cookie,浏览器会保存这个 Cookie,并在后续请求中自动携带它。
🧠 详细解释
1. ctx.cookies.set('key', 'value') —— 设置 Cookie
ctx.cookies.set('token', 'abc123');
- 这个操作会在响应头中添加一个
Set-Cookie: token=abc123; ...。 - 浏览器接收到这个响应后,会把
token=abc123存储起来。 - 下次访问同一个域名下的接口时,浏览器会自动把这个 Cookie 携带过去。
✅ 相当于前端设置的 Cookie,但由服务端发起。
2. ctx.session.xxx = xxx —— 使用 Session(会话)
ctx.session.userinfo = { access_token: 'abc123' };
- 这个值并不是直接存储在浏览器中,而是存储在服务端(比如内存、Redis、文件等),具体取决于你配置的 session 存储方式。
- Koa 会通过一个加密的
session ID(通常是一个 Cookie,如koa:sess=...)与客户端保持关联。 - 浏览器只保存这个
session ID的 Cookie,真正数据保留在服务端。
✅ Session 是服务端存储机制,使用 Cookie 来标识用户身份。
🔁 对比总结
| 类型 | 前端是否可见 | 是否持久化 | 安全性 | 存储位置 | 用途 |
|---|---|---|---|---|---|
ctx.cookies.set() | ✅ 是 | ✅ 可以设置过期时间 | ❌ 较低(可被 JS 读取) | 浏览器 Cookie | 存储小型非敏感数据(如 token) |
ctx.session.xxx | ❌ 否 | ✅ 可控制过期时间 | ✅ 高(数据不暴露给客户端) | 服务端 + Cookie ID | 存储敏感信息(如用户登录状态) |
📌 举个例子说明流程
当你调用:
ctx.session.userinfo = user;
实际过程如下:
- Koa 把
userinfo数据序列化并加密后保存到服务端(例如 Redis)。 - 生成一个唯一的 Session ID,比如
abc123xyz。 - 设置一个 Cookie:
koa:sess=abc123xyz发送给浏览器。 - 下次浏览器再发请求时,带上这个 Cookie。
- Koa 根据 Cookie 中的 Session ID 找到对应的服务端数据,还原成
ctx.session.userinfo。
🚫 不要混淆以下概念:
| 名称 | 类型 | 特点 |
|---|---|---|
SessionStorage / LocalStorage | 前端浏览器 API | 存储在前端,可通过 JS 操作 |
Cookie | HTTP 协议机制 | 浏览器和服务器共享,自动发送 |
Session(Koa) | 服务端会话机制 | 数据存在服务端,通过 Cookie 关联用户 |
✅ 总结建议
-
如果你想存储敏感信息(如
access_token):推荐使用ctx.session。 -
如果你想存储轻量级、非敏感信息(如用户偏好、临时 token):可以使用
ctx.cookies.set()。 -
如果你在前端想获取这些数据:
- Cookie 中的内容可以用
document.cookie读取(前提是未设置httpOnly)。 - Session 中的内容无法直接从浏览器读取,只能通过接口查询。
- Cookie 中的内容可以用