You need to enable JavaScript to run this app. Fastify+Prisma+Postgres场景下如何关联Prisma连接池存储Session
优惠活动
大模型
产品
解决方案
定价
更多

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连接池即可,步骤如下:

  1. 先把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()
  })
})
  1. 调整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();
  1. 修改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操作,和你现有开发习惯完全一致:

  1. 同样先完成上面的前置准备和Prisma插件注册
  2. 修改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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.09 14:24:00