ExpressJS - Cookies
Express.js - 管理 Cookies
Section titled “Express.js - 管理 Cookies”HTTP cookie 是服务器发送给用户网络浏览器的一小段数据。浏览器会存储它们,并在每次后续请求发送到同一服务器时将其传回。Cookie 对于会话管理(如跟踪登录)、个性化(如用户偏好)和用户跟踪等功能至关重要。
要在 Express 中使用 cookie,你需要 cookie-parser 中间件。它会解析传入请求中的 Cookie 头部,并将 req.cookies 对象填充为以 cookie 名称为键的键值对。它还添加了 res.cookie() 方法来设置 cookie。
设置与基本用法
Section titled “设置与基本用法”首先,安装 cookie-parser 作为依赖项:
npm install cookie-parser接下来,在你的 index.js 中导入并将其作为中间件应用。重要的是,要将其放置在任何需要访问 cookie 的路由之前。
import express from 'express';import cookieParser from 'cookie-parser';
const app = express();
// 应用 cookie-parser 中间件// 稍后我们将为签名 cookie 添加一个密钥app.use(cookieParser());
// ... 你的路由设置和读取 Cookie
Section titled “设置和读取 Cookie”让我们创建两个路由:一个用于设置 cookie,另一个用于读取它。
index.js
Section titled “index.js”// 设置 cookie 的路由app.get('/set-cookie', (req, res) => { // 设置一个名为 'userTheme'、值为 'dark' 的 cookie res.cookie('userTheme', 'dark'); res.send('Cookie 已设置!请检查你的浏览器开发者工具。');});
// 读取 cookie 的路由app.get('/get-cookie', (req, res) => { // 从请求对象中访问 cookie const theme = req.cookies.userTheme; if (theme) { res.send(`你的主题设置为: ${theme}`); } else { res.send('未找到主题 cookie。'); }});
// ... app.listen运行服务器后,首先访问 http://localhost:3000/set-cookie。然后,访问 http://localhost:3000/get-cookie。你应该会看到确认你主题的消息。你还可以在浏览器的开发者工具中检查存储的 cookie(通常在“应用程序”或“存储”选项卡中)。
安全 Cookie 的最佳实践
Section titled “安全 Cookie 的最佳实践”仅仅设置一个 cookie 对于生产应用程序来说通常是不够的。你必须安全地配置它们,以防止常见的攻击,如跨站脚本 (XSS) 和跨站请求伪造 (CSRF)。
res.cookie() 方法接受一个选项对象作为其第三个参数。以下是最重要的安全选项:
**httpOnly: true**:这至关重要。它阻止客户端 JavaScript (document.cookie) 访问 cookie。这可以缓解攻击者试图窃取 cookie 的 XSS 攻击。**secure: true**:确保 cookie 仅通过 HTTPS 连接发送。在生产环境中,你应始终启用此选项。**sameSite: ‘strict’或’lax’**:防御 CSRF 攻击的强大手段。'strict'阻止浏览器在任何跨站请求中发送 cookie。'lax'是一个合理的默认值,允许在顶级导航(例如,点击来自其他网站的链接)时发送 cookie。**maxAge或expires**:设置 cookie 的过期时间。maxAge是从当前开始的毫秒数,而expires是一个特定的Date对象。
示例:设置安全 Cookie
Section titled “示例:设置安全 Cookie”app.get('/set-secure-cookie', (req, res) => { const options = { maxAge: 7 * 24 * 60 * 60 * 1000, // 7 天的毫秒数 httpOnly: true, // 该 cookie 仅能由 Web 服务器访问 secure: process.env.NODE_ENV === 'production', // 仅在 HTTPS 上设置 sameSite: 'lax' // 或 'strict' };
res.cookie('sessionToken', 'abc123xyz', options); res.send('安全 cookie 已设置!');});签名 Cookie
Section titled “签名 Cookie”Cookie 存储在客户端,可能会被篡改。为了确保 cookie 的值未被更改,你可以使用签名 cookie。如果你向 cookie-parser 提供一个密钥字符串,它就可以实现这一点。
重要提示:你的密钥应该是一个长而随机的字符串,安全地存储为环境变量,而不是硬编码。
index.js(更新后的设置)
Section titled “index.js(更新后的设置)”// 出于安全考虑,密钥应来自环境变量const COOKIE_SECRET = process.env.COOKIE_SECRET || 'default-secret';
app.use(cookieParser(COOKIE_SECRET));设置和读取签名 Cookie
Section titled “设置和读取签名 Cookie”// 设置签名 cookieapp.get('/set-signed-cookie', (req, res) => { res.cookie('userRole', 'admin', { signed: true }); res.send('签名 cookie 已设置。');});
// 读取签名 cookieapp.get('/get-signed-cookie', (req, res) => { // 未签名 cookie 在 req.cookies 中 // 签名 cookie 在 req.signedCookies 中 const userRole = req.signedCookies.userRole;
if (userRole) { res.send(`你的角色是: ${userRole}`); } else { // 如果 cookie 被篡改或未设置,就会出现这种情况 res.status(401).send('无效或缺失角色 cookie。'); }});删除 Cookie
Section titled “删除 Cookie”要删除一个 cookie,请使用 res.clearCookie()。你必须传入与设置时相同的选项(例如 domain 和 path)。
app.get('/logout', (req, res) => { res.clearCookie('sessionToken'); res.send('你已退出登录。');});