Firebase中express-session无法存储Cookie,每次刷新创建新会话求助
我帮你排查了代码里的几个关键问题,这些正是导致会话重复创建、Cookie无法保存的核心原因,咱们一步步来修复:
1. 修正Firebase初始化与数据库引用
在Firebase Functions环境中,不需要手动传入functions.config().firebase来初始化App——Functions会自动加载环境配置。另外,获取数据库实例的方式也需要调整,确保会话存储能正确关联到你的Firebase数据库:
// 替换原来的初始化代码 const firebase = require('firebase-admin'); firebase.initializeApp(); // 无需传入config参数 const db = firebase.database(); // 直接获取数据库实例
2. 补全会话Cookie的必要配置
浏览器现在对Cookie的安全性要求很高,你的代码里缺少secure和sameSite属性,这会导致浏览器拒绝保存Cookie,自然每次请求都会创建新会话。我们可以根据环境自动调整secure值(本地测试用HTTP,生产用HTTPS):
const isProduction = process.env.NODE_ENV === 'production'; app.use(session({ store: new FirebaseStore({ database: db }), // 使用修正后的数据库实例 secret: 'abigsigrettotheseeiosnofthmbiith765huig', resave: false, // 优化:仅在会话修改时才保存 saveUninitialized: false, // 优化:不保存未初始化的空会话 cookie: { maxAge: 60000, secure: isProduction, // 生产环境强制HTTPS,本地测试关闭 sameSite: 'lax', // 符合现代浏览器的Cookie策略 httpOnly: true // 提升安全性,防止XSS攻击 } }));
3. 确认代理信任配置
你已经设置了app.set('trust proxy', 1),这个是对的,但在一些场景下可以改为true,确保Express能正确识别来自Firebase代理的请求:
app.set('trust proxy', true);
修改后的完整代码
const functions = require('firebase-functions'); const express = require('express'); const session = require('express-session'); const FirebaseStore = require('connect-session-firebase')(session); const firebase = require('firebase-admin'); const cookieParser = require('cookie-parser'); // 修正Firebase初始化 firebase.initializeApp(); const db = firebase.database(); const app = express(); app.use(cookieParser()); app.set('trust proxy', true); const isProduction = process.env.NODE_ENV === 'production'; app.use(session({ store: new FirebaseStore({ database: db }), secret: 'abigsigrettotheseeiosnofthmbiith765huig', resave: false, saveUninitialized: false, cookie: { maxAge: 60000, secure: isProduction, sameSite: 'lax', httpOnly: true } })); app.get('/', function(req, res, next) { console.log(req.session); req.session.username='xyz'; res.send('Filling the session with data'); }); app.get('/bar', function(req, res, next) { console.log(req.session); var sessionData = req.session.username; res.send(`This will print the attribute I set earlier: ${sessionData}`); }); exports.app = functions.https.onRequest(app);
测试注意事项
- 本地测试时,使用
firebase emulators:start启动服务,此时isProduction为false,secure会被禁用,浏览器能正常保存Cookie。 - 部署到生产环境后,Firebase会自动启用HTTPS,
secure属性生效,Cookie会被正确保存。
这样修改后,刷新页面时就会复用已有会话,不会重复创建新的会话记录,同时Cookie也能正常存储和携带了。
内容的提问来源于stack exchange,提问作者Rakkefet
相关产品推荐
相关产品推荐

