首页 > web前端 > js教程 > 正文

怎样使用Node.js操作Cookie?

煙雲
发布: 2025-08-30 15:09:01
原创
991人浏览过
答案:Node.js中操作Cookie需借助Express等框架及cookie-parser中间件,通过res.cookie()设置、req.cookies读取、res.clearCookie()清除,并需配置httpOnly、secure、sameSite等安全属性以防范XSS和CSRF攻击。

怎样使用node.js操作cookie?

在Node.js中操作Cookie,本质上是围绕HTTP请求与响应头进行。我们不会像在浏览器里那样直接去“读写”一个全局的

document.cookie
登录后复制
对象,而是在服务器端接收来自客户端的Cookie,或向客户端发送设置Cookie的指令。最常见和推荐的方式,是借助像Express.js这样的Web框架,配合其生态中的中间件,如
cookie-parser
登录后复制
,来简化这一过程。

解决方案

要在Node.js应用中高效且安全地操作Cookie,我们通常会选择一个成熟的Web框架。以Express.js为例,它提供了一套非常直观的API。

首先,你需要安装

express
登录后复制
cookie-parser
登录后复制

npm install express cookie-parser
登录后复制

然后,在你的应用中引入并使用它们:

const express = require('express');
const cookieParser = require('cookie-parser');
const app = express();
const port = 3000;

// 使用cookie-parser中间件。
// 如果你想对Cookie进行签名,可以在这里传入一个秘密字符串(secret)。
// 例如:app.use(cookieParser('your-secret-key'));
app.use(cookieParser());

// 设置Cookie的路由
app.get('/set-cookie', (req, res) => {
  // 设置一个简单的Cookie
  res.cookie('myCookie', 'helloWorld', { maxAge: 900000, httpOnly: true });

  // 设置一个带有更多选项的Cookie
  res.cookie('userSession', 'someUserId123', { 
    expires: new Date(Date.now() + 24 * 3600 * 1000), // 24小时后过期
    httpOnly: true, // 重要的安全选项,防止客户端脚本访问
    secure: process.env.NODE_ENV === 'production', // 仅在HTTPS连接下发送
    sameSite: 'Lax', // 重要的安全选项,防止CSRF攻击
    path: '/', // Cookie对所有路径都可用
    // domain: '.example.com' // 如果需要跨子域共享
  });

  res.send('Cookie已设置!');
});

// 获取Cookie的路由
app.get('/get-cookie', (req, res) => {
  // cookie-parser会将所有Cookie解析到req.cookies对象上
  const myCookie = req.cookies.myCookie;
  const userSession = req.cookies.userSession;

  if (myCookie) {
    res.send(`获取到的myCookie是: ${myCookie},userSession是: ${userSession || '未设置'}`);
  } else {
    res.send('未找到myCookie。');
  }
});

// 清除Cookie的路由
app.get('/clear-cookie', (req, res) => {
  // 清除Cookie需要指定其名称和设置时的路径(如果非默认)
  res.clearCookie('myCookie');
  res.clearCookie('userSession'); // 清除时也要注意path和domain是否匹配

  res.send('Cookie已清除!');
});

app.listen(port, () => {
  console.log(`服务器运行在 http://localhost:${port}`);
});
登录后复制

在这个例子中,

res.cookie()
登录后复制
方法是设置Cookie的关键。它接受Cookie的名称、值以及一个可选的配置对象。这个配置对象里的参数,比如
httpOnly
登录后复制
secure
登录后复制
sameSite
登录后复制
等,对于Cookie的安全性和行为至关重要。而
req.cookies
登录后复制
则是由
cookie-parser
登录后复制
中间件解析后,提供给我们方便访问客户端发送过来的所有Cookie。清除Cookie则通过
res.clearCookie()
登录后复制
来实现,它会发送一个过期时间为过去的
Set-Cookie
登录后复制
头,指示浏览器删除该Cookie。

Node.js中操作Cookie时有哪些常见的安全考量?

在Node.js应用中处理Cookie,安全性绝不是一个可以忽视的环节。我个人觉得,很多开发者,包括我自己在初学时,很容易只关注功能实现而忽略了这些至关重要的安全属性。这些属性的存在,是为了保护用户数据和应用程序免受常见的Web攻击。

  • httpOnly
    登录后复制
    属性: 这是我首推的、最重要的安全设置之一。当一个Cookie被标记为
    httpOnly: true
    登录后复制
    时,客户端的JavaScript就无法通过
    document.cookie
    登录后复制
    来访问它。这意味着,即使你的网站不幸遭受了跨站脚本攻击(XSS),攻击者也无法通过注入恶意JavaScript代码来窃取这个Cookie,从而大大降低了会话劫持的风险。对于存储用户会话ID这类敏感信息的Cookie,
    httpOnly
    登录后复制
    几乎是必选项。

  • secure
    登录后复制
    属性: 如果你的网站使用了HTTPS(现在应该都是标配了),那么
    secure: true
    登录后复制
    也是一个必须的设置。它告诉浏览器,这个Cookie只能通过加密的HTTPS连接发送到服务器,而不能通过不安全的HTTP连接发送。这可以防止Cookie在传输过程中被窃听或篡改。在开发环境,我可能会暂时关闭它,但一旦部署到生产环境,这个开关必须打开。

  • sameSite
    登录后复制
    属性: 这个属性是近年来Web安全领域的一个重要进展,主要用于防御跨站请求伪造(CSRF)攻击。它有三个主要值:

    • Lax
      登录后复制
      (默认值,如果未设置):
      这是相对宽松的模式。在跨站请求中,只有当用户通过顶部导航(如点击链接)或
      GET
      登录后复制
      形式的表单提交时,Cookie才会被发送。像
      <img>
      登录后复制
      标签或
      <iframe>
      登录后复制
      等资源加载请求则不会发送Cookie。对于大多数用户体验影响较小的场景,
      Lax
      登录后复制
      是一个不错的平衡点。
    • Strict
      登录后复制
      这是最严格的模式。只有当请求是同站发起的,或者用户直接从目标网站导航过来时,Cookie才会被发送。任何跨站请求(即使是点击链接)都不会发送Cookie。这提供了最强的CSRF保护,但可能会对一些跨站链接的用户体验造成影响,比如从第三方网站跳转到你的网站时,用户可能需要重新登录。
    • None
      登录后复制
      允许在所有跨站请求中发送Cookie。但必须同时设置
      secure: true
      登录后复制
      ,否则浏览器会拒绝设置该Cookie。这通常用于需要跨站共享Cookie的场景,例如OAuth认证流程、嵌入式内容或某些API调用。但使用时需要格外小心,确保你的应用程序有其他CSRF保护机制。
  • 过期时间 (

    expires
    登录后复制
    maxAge
    登录后复制
    ):
    合理设置Cookie的生命周期非常重要。对于会话Cookie(如登录状态),应该设置一个合理的过期时间,而不是让它永久有效。过长的有效期会增加Cookie被窃取后滥用的风险。对于“记住我”功能,也应谨慎设置,并考虑使用刷新令牌等更安全的机制。

  • Cookie签名 (

    signed
    登录后复制
    ):
    cookie-parser
    登录后复制
    允许你对Cookie进行签名。这意味着,服务器在发送Cookie时会附加一个数字签名。当Cookie返回服务器时,
    cookie-parser
    登录后复制
    会验证这个签名。如果Cookie的值在传输过程中被篡改,签名验证就会失败,从而阻止应用程序使用被篡改的Cookie。这并不能加密Cookie内容,但可以防止客户端篡改非敏感数据(例如用户偏好设置)。对于敏感数据,通常不建议直接存入Cookie,而是通过Session ID配合服务器端存储。

  • 路径 (

    path
    登录后复制
    ) 和域名 (
    domain
    登录后复制
    ):
    精确控制Cookie的作用域可以限制其暴露范围。例如,将Cookie的
    path
    登录后复制
    设置为
    /admin
    登录后复制
    ,则该Cookie只会在访问
    /admin
    登录后复制
    及其子路径时发送。
    domain
    登录后复制
    属性则可以控制Cookie在哪些子域之间共享。不精确的设置可能会导致Cookie在不必要的上下文中被发送,增加泄露风险。

这些安全考量,我个人认为,是构建健壮Web应用的基础。理解它们并正确应用,远比仅仅知道如何设置和获取Cookie来得重要。

除了Express,Node.js还有哪些库或框架可以方便地处理Cookie?

当然,Node.js的生态非常丰富,处理Cookie的方式也多种多样。虽然Express.js搭配

cookie-parser
登录后复制
是最常见的组合,但如果你在使用其他框架,或者甚至是在纯Node.js环境下,也有相应的解决方案。

  • Koa.js: Koa是另一个流行的Node.js Web框架,它以其“洋葱圈”模型和基于

    async/await
    登录后复制
    的中间件而闻名。Koa内置了对Cookie的良好支持,无需额外的中间件(尽管有
    koa-session
    登录后复制
    等可以增强功能)。

    const Koa = require('koa');
    const app = new Koa();
    
    app.use(async (ctx, next) => {
      // 设置Cookie
      ctx.cookies.set('koaCookie', 'helloKoa', {
        maxAge: 900000,
        httpOnly: true,
        secure: process.env.NODE_ENV === 'production',
        sameSite: 'Lax'
      });
    
      // 获取Cookie
      const myKoaCookie = ctx.cookies.get('koaCookie');
      if (myKoaCookie) {
        ctx.body = `获取到的koaCookie是: ${myKoaCookie}`;
      } else {
        ctx.body = '未找到koaCookie。';
      }
    
      // 清除Cookie
      // ctx.cookies.set('koaCookie', null); // 另一种清除方式,将值设为null
      // ctx.cookies.set('koaCookie', '', { expires: new Date(0) }); // 或者设置过期时间为过去
    
      await next();
    });
    
    app.listen(3000, () => {
      console.log('Koa server running on port 3000');
    });
    登录后复制

    Koa的API设计非常简洁,通过

    ctx.cookies.set()
    登录后复制
    ctx.cookies.get()
    登录后复制
    就可以直接操作。我个人觉得,这种设计在现代异步JavaScript中显得更加自然。

  • Hapi.js: Hapi是另一个企业级的Node.js框架,它以其严格的配置和插件系统而著称。Hapi也提供了内置的Cookie处理机制,通常通过其

    state
    登录后复制
    配置来管理。

    const Hapi = require('@hapi/hapi');
    
    const init = async () => {
        const server = Hapi.server({
            port: 3000,
            host: 'localhost'
        });
    
        // 配置Cookie state
        server.state('session', {
            ttl: 24 * 60 * 60 * 1000, // 1 day
            isSecure: process.env.NODE_ENV === 'production',
            isHttpOnly: true,
            encoding: 'base64json', // 可以对Cookie值进行编码
            clearInvalid: false, // 是否清除无效Cookie
            strictHeader: true, // 严格的header解析
            path: '/',
            sameSite: 'Lax'
        });
    
        server.route({
            method: 'GET',
            path: '/set-cookie',
            handler: (request, h) => {
                return h.response('Cookie set!').state('session', { userId: 'hapiUser123' });
            }
        });
    
        server.route({
            method: 'GET',
            path: '/get-cookie',
            handler: (request, h) => {
                const session = request.state.session;
                if (session && session.userId) {
                    return `User ID from session cookie: ${session.userId}`;
                }
                return 'No session cookie found.';
            }
        });
    
        server.route({
            method: 'GET',
            path: '/clear-cookie',
            handler: (request, h) => {
                return h.response('Cookie cleared!').unstate('session');
            }
        });
    
        await server.start();
        console.log('Hapi Server running on %s', server.info.uri);
    };
    
    process.on('unhandledRejection', (err) => {
        console.log(err);
        process.exit(1);
    });
    
    init();
    登录后复制

    Hapi通过

    server.state()
    登录后复制
    方法定义Cookie的配置,然后在路由处理函数中使用
    h.response().state()
    登录后复制
    request.state
    登录后复制
    来设置和获取。它的配置选项非常详尽,适合需要精细控制的场景。

  • 纯Node.js (不使用框架): 如果你选择不使用任何框架,直接使用Node.js的

    http
    登录后复制
    模块,那么你需要手动解析请求头中的
    Cookie
    登录后复制
    字段,并手动设置响应头中的
    Set-Cookie
    登录后复制
    字段。这会涉及到字符串的解析和拼接,相对繁琐且容易出错,这也是为什么我们通常会推荐使用框架或专门的库。

    const http = require('http');
    
    http.createServer((req, res) => {
      if (req.url === '/set-cookie') {
        // 手动设置Set-Cookie头
        res.setHeader('Set-Cookie', [
          'pureNodeCookie=helloPureNode; Max-Age=900; HttpOnly; Path=/',
          'anotherCookie=value2; Expires=' + new Date(Date.now() + 3600000).toUTCString() + '; Path=/; Secure; SameSite=Lax'
        ]);
        res.end('Cookie set by pure Node.js!');
      } else if (req.url === '/get-cookie') {
        // 手动解析Cookie头
        const cookieHeader = req.headers.cookie;
        let cookies = {};
        if (cookieHeader) {
          cookieHeader.split(';').forEach(cookie => {
            const parts = cookie.split('=');
            cookies[parts[0].trim()] = parts[1];
          });
        }
        res.end(`Cookies from pure Node.js: ${JSON.stringify(cookies)}`);
      } else {
        res.end('Hello from pure Node.js!');
      }
    }).listen(3000, () => {
      console.log('Pure Node.js server running on port 3000');
    });
    登录后复制

    这种方式虽然提供了最大的灵活性,但正如你所见,需要处理大量的细节,包括Cookie值的编码、解析,以及各种属性的正确格式化。我个人觉得,除非有非常特殊的需求,否则通常不建议直接采用这种方式。

总的来说,选择哪个库或框架来处理Cookie,很大程度上取决于你项目的整体技术栈。Express和Koa都是非常优秀的选项,它们都提供了强大且易用的Cookie管理功能。

Cookie与Session在Node.js应用中如何协同工作?

在我看来,Cookie和Session的关系,就像是“门票”和“衣帽间凭证”的关系。Cookie是客户端(浏览器)存储的一小段信息,而Session是服务器端存储的用户会话数据。它们通常是协同工作的,Cookie往往被用来承载Session的标识符,而不是Session本身的数据。

核心思想是这样的:

  1. 用户首次访问或登录时:服务器会生成一个唯一的Session ID,并将这个ID存储在一个Cookie中,然后将这个Cookie发送给客户端。
  2. 客户端后续请求:客户端在每次发送请求时,都会自动将这个包含Session ID的Cookie发送回服务器。
  3. 服务器端识别:服务器接收到请求后,会从Cookie中提取Session ID,然后根据这个ID去查找服务器端存储的对应Session数据。

在Node.js应用中,实现这种协同工作最常见的方式是使用

express-session
登录后复制
这样的中间件(如果你使用Express.js)。

const express = require('express');
const session = require('express-session'); // 注意这里是express-session,不是cookie-parser
const app = express();
const port = 3000;

// 配置session中间件
app.use(session({
  secret: 'mySuperSecretKeyForSigningSessionCookie', // 必须提供一个秘密字符串来签名Session ID Cookie
  resave: false, // 强制session保存到session store中,即使在请求中没有被修改
  saveUninitialized: false, // 强制未初始化的session保存到session store中
  cookie: {
    maxAge: 1000 * 60 * 60 * 24, // Session Cookie的有效期,例如24小时
    httpOnly: true,
    secure: process.env.NODE_ENV === 'production',
    sameSite: 'Lax',
  }
  // store: new RedisStore({ client: redisClient }) // 如果需要将session存储到外部数据库,如Redis
}));

// 登录路由,设置session
app.get('/login', (req, res) => {
  req.session.userId = 'user123';
  req.session.username = 'Alice';
  req.session.loggedIn = true;
  res.send('登录成功,Session已设置!');
});

// 获取session数据的路由
app.get('/profile', (req, res) => {
  if (req.session.loggedIn) {
    res.send(`欢迎回来,${req.session.username}!你的ID是:${req.session.userId}`);
  } else {
    res.status(401).send('请先登录。');
  }
});

// 登出路由,销毁session
app.get('/logout', (req, res) => {
  req.session.destroy((err) => {
    if (err) {
      return res.status(500).send('登出失败。');
    }
    res.send('登出成功,Session已销毁!');
  });
});

app.listen(port, () => {
  console.log(`服务器运行在 http://localhost:${port}`);
});
登录后复制

在这个例子中:

  • express-session
    登录后复制
    中间件会自动处理Session ID的生成、存储到Cookie、以及从Cookie中读取Session ID并加载对应的Session数据。
  • req.session
    登录后复制
    对象就是服务器端存储的用户会话数据。你可以在这里存储任何非敏感的用户状态信息,例如用户ID、用户名、登录状态、购物车内容等。
  • secret
    登录后复制
    选项至关重要,它用于签名Session ID Cookie,防止客户端篡改。
  • Cookie
    登录后复制
    选项则允许你配置Session ID Cookie本身的各种属性,如
    maxAge
    登录后复制
    httpOnly
    登录后复制
    secure
    登录后复制
    sameSite
    登录后复制
    ,这些都和前面提到的Cookie安全考量一致。

为什么Session比直接在Cookie中存储所有数据更安全? 我个人认为,Session的优势在于它将大部分敏感数据保留在服务器端。如果直接把所有用户数据都塞进Cookie,不仅有大小限制,而且如果Cookie没有加密或签名不当,客户端就可能篡改或窃取这些数据。Session ID只是一个不包含实际信息的随机字符串,即使它被窃取,攻击者也只能通过它访问服务器上存储的数据,而无法直接从Cookie中获取敏感信息。

Session的权衡: 虽然Session提供了更好的安全性,但它也有其代价。

  • 服务器资源消耗: 每个活动会话都会占用服务器内存(如果使用默认的内存存储),这在高并发场景下可能成为瓶颈。
  • 分布式部署挑战: 在负载均衡的集群环境中,需要一个共享的Session存储(如Redis、MongoDB或数据库)来确保用户在不同服务器之间切换时,其会话数据仍然可用。这就是为什么
    express-session
    登录后复制
    提供了
    store
    登录后复制
    选项。

总而言之,Cookie和Session是Web应用中管理用户状态的两种互补机制。Cookie负责在客户端和服务器之间传递一个标识符,而Session则在服务器端维护这个标识符所代表的完整用户状态。理解它们各自的职责和协同方式,对于构建安全、可扩展的Node.js应用至关重要。

以上就是怎样使用Node.js操作Cookie?的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号