使用Session
Express本身没有对Session进行支持,不过我们可以使用express-session库,它以中间件的形式封装了Session实现,底层可以使用内存、Redis、MongoDB等后端保存数据。
安装express-session
执行以下命令安装express-session库。
npm i express-session
基本使用
下面是一个简单的例子,我们使用基于内存的Session后端。
import express from "express";
import expressSession from "express-session";
const app = express();
// 初始化Session中间件
const session = expressSession({
secret: "G1Wdumt0xvLFtnbBTvj%GKeDpw5xjkCv!HViqSWJ$cKPAun@Gq",
resave: true,
saveUninitialized: false,
});
// 注册Session中间件
app.use(session);
// 路由处理
app.get("/", (req, res) => {
// 读取Session
const user = req.session.user;
console.log(user);
// 写入Session
req.session.user = { name: "Tom", age: 18 };
res.sendStatus(200);
});
app.listen(8080, () => {
console.log("Express server listen on 8080");
});
代码中,我们首先初始化了Session中间件,常用配置项如下:
secret:加密密钥,express-session会使用该密钥对Session ID进行签名,防止被篡改resave:是否在Session未改变时也强制重新保存,一般设置为truesaveUninitialized:是否保存未初始化的Session,一般设置为false
session对象实际上是一个Express中间件,我们需要使用app.use()将其添加到框架中,注意它需要设置在路由处理之前。在具体的处理函数中,我们直接对req.session属性进行读写即可实现对Session数据的读写。
注意:默认情况下,Cookie中保存Session ID的键名为connect.sid。
常用配置项
除了上面介绍的基本配置外,express-session还支持更多配置项。
const session = expressSession({
secret: "your-secret-key",
resave: true,
saveUninitialized: false,
name: "sessionId",
cookie: {
maxAge: 1000 * 60 * 60 * 24, // 过期时间,单位毫秒
httpOnly: true,
secure: false,
},
});
name:Cookie中Session ID的键名,默认为connect.sidcookie.maxAge:Session过期时间,单位为毫秒cookie.httpOnly:是否禁止JavaScript访问Cookie,建议设置为truecookie.secure:是否仅在HTTPS下传输Cookie,生产环境建议设置为true
销毁Session
我们可以调用req.session.destroy()方法销毁当前Session,这在用户退出登录等场景中非常有用。
app.get("/logout", (req, res) => {
req.session.destroy((err) => {
if (err) {
console.error("Session destroy error:", err);
res.sendStatus(500);
} else {
res.sendStatus(200);
}
});
});
使用Redis作为Session存储
在生产环境中,基于内存的Session存储存在一些问题:服务重启后Session数据会丢失,多进程或分布式部署时Session无法共享。我们可以使用Redis作为Session存储后端来解决这些问题。
首先安装connect-redis库。
npm i connect-redis redis
然后配置Redis作为Session存储。
import express from "express";
import expressSession from "express-session";
import RedisStore from "connect-redis";
import { createClient } from "redis";
const app = express();
// 创建Redis客户端
const redisClient = createClient({
url: "redis://localhost:6379",
});
redisClient.connect().catch(console.error);
// 初始化Session中间件
const session = expressSession({
store: new RedisStore({ client: redisClient }),
secret: "G1Wdumt0xvLFtnbBTvj%GKeDpw5xjkCv!HViqSWJ$cKPAun@Gq",
resave: false,
saveUninitialized: false,
});
app.use(session);
app.get("/", (req, res) => {
const user = req.session.user;
console.log(user);
req.session.user = { name: "Tom", age: 18 };
res.sendStatus(200);
});
app.listen(8080, () => {
console.log("Express server listen on 8080");
});
使用Redis作为存储后端时,resave配置项建议设置为false,因为Redis存储本身会自动处理过期时间的刷新。
作者:Gacfox
版权声明:本网站为非盈利性质,文章如非特殊说明均为原创,版权遵循知识共享协议CC BY-NC-ND 4.0进行授权,转载必须署名,禁止用于商业目的或演绎修改后转载。