Skip to content

S08-06 Node-自动化部署、Cookie、Session、token

[TOC]

自动化部署

Cookie 是一个 HTTP 请求标头,其中含有先前由服务器通过 Set-Cookie 标头投放或通过 JavaScript 的 document.cookie 方法设置,然后存储到客户端的 HTTP cookie 。

语法

Set-Cookie 头部用于在 HTTP 响应中设置 Cookie。包含多个可选参数,允许你精确控制 Cookie 的行为和有效期。

js
Set-Cookie: <cookie-name>=<cookie-value>[; <attribute1>=<value1>][; <attribute2>=<value2>]...

参数:

  • <cookie-name>=<cookie-value>:设置的cookie,一次只能设置一个cookie。要设置多个 cookie,则应在同一响应中设置多个 Set-Cookie 标头。
  • [; <attribute1>=<value1>][; <attribute2>=<value2>]...:可选参数,用于精确控制 Cookie 的行为和有效期,通常用分号;分隔。
    • ExpiresHTTP-date,设置 Cookie 的过期时间。如:Expires=Wed, 21 Oct 2025 07:28:00 GMT
    • Max-Agenumber,从设置 Cookie 的时间开始,指定 Cookie 的有效秒数。如:Max-Age=3600
    • Domainstring,指定 Cookie 所属的域名。如果不设置,默认为发送 Cookie 的请求的域名。如:Domain=example.com
    • Pathstring,指定 Cookie 可用的 URL 路径。如果不设置,默认为发送 Cookie 的请求路径。如:Path=/(表示整个网站可用)。
    • Securevoid,指示 Cookie 仅在 HTTPS 连接中发送。
    • HttpOnlyboolean,指示 Cookie 不能通过 JavaScript 的 Document.cookie 访问,提高安全性。
    • SameSiteStrict | Lax | None ,用于控制浏览器在跨站请求时如何处理 Cookie。防止如跨站请求伪造(CSRF)的攻击。
      • Strict:仅在同站请求时发送 Cookie。
      • Lax:默认,允许在同站请求和某些跨站请求(例如 GET 请求点击链接)时发送 Cookie。
      • None不限制 Cookie 的发送,跨站请求时也会发送 Cookie。
        • *注意:*当使用 SameSite=None 时,必须同时设置 Secure 属性,以确保 Cookie 仅通过 HTTPS 连接发送。

注意:

  • Set-Cookie 是服务器发送 Cookie 的方式,出于安全考虑,浏览器不会暴露此头部给前端代码,但允许通过 document.cookie 访问和设置非 HttpOnly 的 Cookie。
  • Cookie的大小限制: 单个 Cookie 的大小通常限制在 4KB 左右,整体数量也有限制(大约 20-50 个)。
  • 由于隐私和安全原因,某些浏览器可能对第三方 Cookie 有额外的限制。

示例: 完整的Set-Cookie,使用了所有的属性

js
Set-Cookie: sessionId=abc123; Expires=Wed, 21 Oct 2025 07:28:00 GMT; Max-Age=86400; Domain=example.com; Path=/; Secure; HttpOnly; SameSite=Lax

示例: Set-Cookie设置多个cookie

js
Set-Cookie: name=tom; Expires=Wed, 21 Oct 2025 07:28:00 GMT // name=tom;
Set-Cookie: age=18; Secure; SameSite=None // age=18;

服务端

原生Node

设置:

在原生Node中可以通过 res.setHeader('Set-Cookie', 'key=value; ...options') 设置Cookie。

js
const http = require('http');

const server = http.createServer((req, res) => {
    // 设置 Cookie
    res.setHeader('Set-Cookie', 'username=JohnDoe; HttpOnly; Max-Age=3600'); // 有效期 1 小时
    res.writeHead(200, { 'Content-Type': 'text/plain' });
    res.end('Cookie has been set');
});

server.listen(3000, () => {
    console.log('Server is running on http://localhost:3000');
});

获取:

在原生 Node.js 中,可以通过 req.headers.cookie 获取cookie,但此时获取到的是cookie字符串,你需要手动解析请求头中的 Cookie:

js
const http = require('http');

const server = http.createServer((req, res) => {
    if (req.headers.cookie) {
        // 获取并解析cookie
        const cookies = req.headers.cookie.split('; ').reduce((acc, cookie) => {
            const [key, value] = cookie.split('=');
            acc[key] = value;
            return acc;
        }, {});
        res.writeHead(200, { 'Content-Type': 'text/plain' });
        res.end(`Username: ${cookies.username}`);
    } else {
        res.writeHead(200, { 'Content-Type': 'text/plain' });
        res.end('No cookies found');
    }
});

server.listen(3000, () => {
    console.log('Server is running on http://localhost:3000');
});

Express

设置:

在原生Express中可以通过 res.cookie(key, value, {...options})设置Cookie。

js
const express = require('express');
const app = express();

app.get('/set-cookie', (req, res) => {
    res.cookie('username', 'JohnDoe', { httpOnly: true, maxAge: 3600000 }); // 有效期 1 小时
    res.send('Cookie has been set');
});

app.listen(3000, () => {
    console.log('Server is running on http://localhost:3000');
});

获取:

在 Express 中,使用 cookie-parser 中间件可以方便地访问 Cookie:

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

app.use(cookieParser());

app.get('/get-cookie', (req, res) => {
    const username = req.cookies.username; // 直接获取 Cookie
    res.send(`Username: ${username || 'No cookie found'}`);
});

app.listen(3000, () => {
    console.log('Server is running on http://localhost:3000');
});

浏览器

设置:

在浏览器中可以通过document.cookie设置cookie。

js
document.cookie = "username=JohnDoe; expires=Fri, 31 Dec 2024 23:59:59 GMT; path=/; Secure; SameSite=Lax"; // username=JohnDoe;

获取:

在浏览器中可以通过document.cookie获取cookie。

js
let cookies = document.cookie;
console.log(cookies); // 输出所有 Cookie

删除:

要删除 Cookie,只需设置一个过期日期为过去的时间

js
document.cookie = "username=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/";

session

token

JWT

  • jwt.sign(payload, privateKey, {expiresIn, algorithm}) :颁发 token
  • jwt.verify(token, publicKey, {algorithm}) :验证 token

非对称加密

生成公钥和私钥

使用 openssl 来生成一对私钥和公钥

sh
# 1. 进入到保存公钥和私钥的目录中
cd 保存目录

# 2. 进入SSL的REPL
openssl

# 3. 生成私钥和公钥
genrsa -out private.key 1024 # 生成私钥 private.key
rsa -in private.key -pubout -out public.key # 生成公钥 public.key