Node.js - Cookie与Session详解

1.1 Cookie与cookie-parser

Cookie 是由 网页服务器 在用户浏览网页时存储在 浏览器 中的一小段文本数据,主要用于在客户端和服务器之间传递信息。它在用户访问网站时记录和跟踪用户的状态和行为。

在Node.js中,开发者通常使用cookie-parser处理cookie。cookie-parser 是一个流行的中间件,用于处理和解析 HTTP 请求中的 Cookie,通常用于 Express 应用中

bash 复制代码
npm i cookie-parser //node.js安装cookie-parser
javascript 复制代码
const cookieParser = require("cookie-parser");
app.use(cookieParser());

1.2 cookie设置

设置未签名cookie

设置cookie是在request请求中自带,不需要依赖其他包进行设置

javascript 复制代码
//语法
res.cookie(name,value,options)
javascript 复制代码
app.get('/set-cookie',(req,res)=>{
    //res.cookie('name','Ricardo') //浏览器关闭之后就会销毁
    res.cookie('name','ricardo',{maxAge:60*1000}) //长时间保存 1000为1s
    res.cookie('age':'12')
    res.send('home')
})

设置签名cookie

签名密钥:密钥(secret)与不同的值(value)结合时会生成不同的签名。这是密钥签名机制的核心原理。如果在客户端篡改cookie值,与原有密钥会生成不同的请求签名,发送请求时,会携带原始签名,服务端计算cookie值与密钥生成判断签名,验证携带来的原始签名与判断签名判断客户端是否修改cookie

javascript 复制代码
app.use(cookieParser("my-secret-key"));

// 设置签名 Cookie
app.get("/set-signed-cookie", (req, res) => {
    res.cookie("userId", "12345", { signed: true });
    res.send("Signed Cookie has been set!");
})

如果客户端篡改了 Cookie 值,req.signedCookies 不会返回该字段。

设置Cookie相关参数:通过对象类型传递

|----------|-------------------------------------|
| maxAge | Cookie的有效时长 |
| httpOnly | 禁止客户端通过JavaScript访问此cookie,默认为false |
| secure | 仅在HTTPS环境中传输,默认为false |
| signed | 启用签名验证(需要设置签名密钥) |

1.3 获取cookie

如果没有使用 cookie-parser中间件req.cookies 是未定义的,服务器端无法直接解析请求中的 Cookie 数据。如果没有使用cookie-parser,则需要手动从 req.headers.cookie 中解析这些数据

javascript 复制代码
//获取cookies
app.get('/get-cookie',(req,res)=>{
    //获取cookie
    console.log(req.cookies)
    const signedCookies = req.signedCookies; //获取签名cookies

    res.send("获取cookie")
})

1.4 清除cookie

使用clearCookie方法清除cookie

javascript 复制代码
//删除cookie
app.get('/remove-cookie',(req,res)=>{
    res.clearCookie('Cookie-name')
    res.send('删除成功')
})

2. session

2.1 什么是session

实现会话控制,可以识别用户的身份,快速获取当前用户的相关信息

填写账号和密码校验身份,校验通过后创建session信息,然后将session_id的值通过响应头返回给浏览器

通俗来讲,session就是cookie的索引机制,服务端通过 Session ID 自动匹配和判断 Session 是否属于当前客户端。这是 Session 机制的核心工作原理,服务器通过cookie中的session_id的值确认用户的身份

2.2 session配置

在Node.js中,使用express-session进行配置与管理session

bash 复制代码
npm i express-session //安装

配置session中间件:

javascript 复制代码
const session = require(// 配置 session 中间件
app.use(session({
    secret: "my-secret-key", // 用于加密 session ID 的密钥
    resave: false,           // 每次请求是否强制保存 session
    saveUninitialized: true, // 是否为未初始化的 session 保存数据
    cookie: { maxAge: 60000 } // 设置 cookie 的过期时间(毫秒)
}));"express-session");

session配置项:

|-------------------|------------------------------------------------|
| secret | 必填项,指定一个用于加密 Session ID 的字符串 |
| resave | 是否在每次请求时强制重新保存 Session,即使它没有被修改,通常为false提高性能 |
| saveUninitialized | 是否为未初始化的 Session(未存储数据)分配存储空间 |
| cookie | 用于配置 Session 的 Cookie 属性,例如过期时间、是否仅在 HTTPS 下传输 |
| store | session存储在服务器中的位置 |

默认情况下,Session 是存储在服务器内存中的。但对于大规模应用,可能会导致性能问题

常见存储在MongoDB中:

bash 复制代码
npm install connect-mongo
javascript 复制代码
const MongoStore = require("connect-mongo");
app.use(session({
    secret: "my-secret-key",
    store: MongoStore.create({ mongoUrl: "mongodb://localhost:27017/session-db",
                                collectionName:"sessions", }), //自定义存储session的集合名称
    resave: false,
    saveUninitialized: true
}));

2.3 session操作

以下示例演示如何设置、获取和销毁 Session:

javascript 复制代码
app.get("/set-session", (req, res) => {
    req.session.username = "Alice";
    res.send("Session data has been saved.");
});

app.get("/get-session", (req, res) => {
    if (req.session.username) {
        res.send(`Hello, ${req.session.username}`);
    } else {
        res.send("No session data found.");
    }
});

app.get("/destroy-session", (req, res) => {
    req.session.destroy((err) => {
        if (err) {
            return res.status(500).send("Unable to destroy session.");
        }
        res.send("Session has been destroyed.");
    });
});

其中设置cookie为键值对为username:Alice

总结:session与cookie的区别

|-------|-------------------|--------------------|
| 区别 | cookie | session |
| 存放位置 | 浏览器端 | 服务端 |
| 安全性 | 明文存放,安全性较低 | 存放服务器,安全性较好 |
| 网络传输量 | 增大体积,影响效率 | 通过cookie传递id,不影响效率 |
| 存储限制 | 单个cookie存储数据不超过4k | 存储在服务器中,无限制 |

相关推荐
Piper蛋窝4 小时前
深入 Go 语言垃圾回收:从原理到内建类型 Slice、Map 的陷阱以及为何需要 strings.Builder
后端·go
Bug退退退1235 小时前
RabbitMQ 高级特性之死信队列
java·分布式·spring·rabbitmq
prince056 小时前
Kafka 生产者和消费者高级用法
分布式·kafka·linq
六毛的毛7 小时前
Springboot开发常见注解一览
java·spring boot·后端
AntBlack7 小时前
拖了五个月 ,不当韭菜体验版算是正式发布了
前端·后端·python
31535669137 小时前
一个简单的脚本,让pdf开启夜间模式
前端·后端
uzong7 小时前
curl案例讲解
后端
菜萝卜子7 小时前
【Project】基于kafka的高可用分布式日志监控与告警系统
分布式·kafka
一只叫煤球的猫8 小时前
真实事故复盘:Redis分布式锁居然失效了?公司十年老程序员踩的坑
java·redis·后端
大鸡腿同学9 小时前
身弱武修法:玄之又玄,奇妙之门
后端