Fastify+Prisma+Postgres场景下如何关联Prisma连接池存储Session
解决方案
前置准备:定义Session表的Prisma模型
首先在你的schema.prisma中添加UserSession模型,和session存储要求的字段对齐:
model UserSession { sid String @id @db.VarChar(255) sess Json expire DateTime @db.Timestamp(6) }
执行prisma migrate dev生成对应数据库表。
方案1:复用Prisma底层连接池(适配connect-pg-simple)
如果你用的是connect-pg-simple作为SessionStore,直接取Prisma暴露的原生PG连接池即可,步骤如下:
- 先把Prisma Client注册为Fastify全局装饰器
新建prisma.js插件:
const { PrismaClient } = require('@prisma/client') const fp = require('fastify-plugin') module.exports = fp(async (fastify) => { const prisma = new PrismaClient() await prisma.$connect() fastify.decorate('prisma', prisma) // 服务关闭时断开Prisma连接 fastify.addHook('onClose', async (fastify) => { await fastify.prisma.$disconnect() }) })
- 调整server.js加载顺序,先加载Prisma插件再加载Session插件:
const fastify = require('fastify')({ logger: true }); const PORT = process.env.PORT || 3000; // 先注册Prisma fastify.register(require('./prisma')); // 再注册Session fastify.register(require('./sessions')); // 路由注册 // ... const start = async () => { try { await fastify.listen(PORT, '0.0.0.0'); } catch (error) { fastify.log.error(error); process.exit(1); } }; start();
- 修改sessions.js配置,直接传入Prisma的原生连接池:
首先安装依赖:npm install connect-pg-simple
const cookie = require('fastify-cookie'); const session = require('fastify-session'); const fp = require('fastify-plugin'); const pgSession = require('connect-pg-simple')(session); const plugin = async (fastify) => { fastify.register(cookie); fastify.register(session, { secret: process.env.SESSION_SECRET, store: new pgSession({ tableName: 'UserSession', pool: fastify.prisma.$pool, // 直接用Prisma暴露的原生PG连接池 }), saveUninitialized: false, cookie: { httpOnly: true, secure: process.env.NODE_ENV === 'production', // 生产环境开https要设为true maxAge: 24 * 60 * 60 * 1000 // 1天有效期,按需调整 }, }); // 注意:不要每次请求都重置session.user,否则会覆盖已登录状态,改成不存在才初始化 fastify.addHook('preHandler', (req, reply, next) => { if (!req.session.user) req.session.user = {}; next(); }); }; module.exports = fp(plugin);
方案2:自定义Prisma Session Store(更推荐,无底层依赖)
不用第三方Store,自己实现符合fastify-session要求的Store类,完全用Prisma Client操作,和你现有开发习惯完全一致:
- 同样先完成上面的前置准备和Prisma插件注册
- 修改sessions.js直接用自定义Store:
const cookie = require('fastify-cookie'); const session = require('fastify-session'); const fp = require('fastify-plugin'); // 自定义Prisma Session Store class PrismaSessionStore { constructor(prisma) { this.prisma = prisma; } // 获取session async get(sid) { const session = await this.prisma.userSession.findUnique({ where: { sid } }); if (!session) return null; if (new Date() > session.expire) { await this.destroy(sid); return null; } return session.sess; } // 保存session async set(sid, sess, ttl) { const expire = new Date(Date.now() + ttl); await this.prisma.userSession.upsert({ where: { sid }, update: { sess, expire }, create: { sid, sess, expire } }); } // 删除session async destroy(sid) { await this.prisma.userSession.deleteMany({ where: { sid } }); } } const plugin = async (fastify) => { fastify.register(cookie); fastify.register(session, { secret: process.env.SESSION_SECRET, store: new PrismaSessionStore(fastify.prisma), // 直接传入Prisma实例 saveUninitialized: false, cookie: { httpOnly: true, secure: process.env.NODE_ENV === 'production', maxAge: 24 * 60 * 60 * 1000 }, }); fastify.addHook('preHandler', (req, reply, next) => { if (!req.session.user) req.session.user = {}; next(); }); }; module.exports = fp(plugin);
内容的提问来源于stack exchange,提问作者user616
相关产品推荐
相关产品推荐

