HTTP 协议是无状态的——服务器处理完一个请求就忘了你是谁。但网站需要记住用户的登录状态、购物车内容、浏览偏好,这就需要"会话保持"技术。Session 和 Cookie 是实现会话保持的两大工具,它们常被混淆,却有着本质区别。本篇帮你在企业官网开发中正确选用。
一、Cookie 与 Session 的本质区别
Cookie 存在浏览器端,每次请求自动带上,适合存少量、非敏感的数据。Session 存在服务器端(文件/Redis/数据库),浏览器只持有一个 Session ID(通过 Cookie 传递),适合存大量、敏感的数据。简单说:Cookie 是"客户口袋里的便条",Session 是"服务器账本上的记录,客户只拿个编号"。
- 存储位置:Cookie 在浏览器,Session 在服务器。
- 容量限制:Cookie 单条约 4KB,Session 几乎不限。
- 安全性:Cookie 易被查看篡改,Session 用户不可见。
- 生命周期:Cookie 可设长期,Session 默认随浏览器关闭失效。
两者的关系是:Session 依赖 Cookie 传递 Session ID。浏览器首次访问时,服务器创建 Session 并把 ID 通过 Cookie 下发给浏览器;之后每次请求,浏览器带上这个 Cookie,服务器据此找到对应 Session。所以"用 Session 还是 Cookie"不是二选一,而是"敏感数据放 Session,靠 Cookie 传 ID"。
二、登录状态保持方案
登录是最典型的会话场景。用户输入账号密码验证通过后,服务器把用户信息存入 Session,后续请求凭 Session ID 识别身份。下面是尧图常用的登录流程实现:
// 登录处理
function login(username, password) {
const user = db.findUser(username);
if (!user || !verifyPassword(password, user.password)) {
return fail('账号或密码错误');
}
// 用户ID存入Session,标记为已登录
$_SESSION['user_id'] = user.id;
$_SESSION['login_time'] = Date.now();
return success('登录成功');
}
// 鉴权中间件:每个需登录的接口先校验
function requireLogin() {
if (!$_SESSION['user_id']) {
redirect('/login'); // 未登录跳转
}
}
// 退出登录:销毁Session
function logout() {
session_destroy();
redirect('/');
}
如果要实现"记住我"(关闭浏览器后仍保持登录),单靠默认 Session 不行(它随浏览器关闭失效)。这时要配合 Cookie:登录时下发一个长期有效的"记住我令牌"到 Cookie,下次访问时用令牌换回 Session。令牌要随机、可撤销、绑定用户,避免被伪造。
三、安全防护要点
会话机制是攻击者的重点目标,必须做好防护。尧图项目里会强制落实以下几条安全策略:
// Cookie 安全属性设置
Set-Cookie: sessionid=xxx;
HttpOnly; // 禁止JS读取,防XSS窃取
Secure; // 仅HTTPS传输
SameSite=Lax; // 防CSRF跨站请求
Max-Age=7200; // 2小时过期
Path=/
HttpOnly:禁止 JavaScript 读取 Cookie,防止 XSS 攻击窃取会话。Secure:只通过 HTTPS 传输,防中间人窃听。SameSite:限制跨站携带,防 CSRF 攻击。- Session ID 要用高强度随机数生成,登录后重新生成 ID(防固定会话攻击)。
另外,敏感数据绝不能明文存 Cookie。曾经有项目把用户角色存进 Cookie 用于鉴权,结果用户改一下 Cookie 就把自己变成了管理员——这是典型的反面教材。记住原则:Cookie 只存标识和偏好,鉴权数据一律放服务端 Session。把这些安全细节做扎实,企业官网的登录体系才能经得起考验。