部署Firebase后POST请求认证失败,GET请求正常求助
问题描述
本地环境中认证流程验证正常,所有GET和POST请求均可运行,但部署Firebase Functions和Hosting后,仅GET请求成功,POST请求失败,浏览器报错:
TypeError: Cannot read properties of undefined (reading 'isLoggedIn') at C:\Users\helez\appAdmin-Artvinca\functions\app.js:118:34 at Layer.handle_error (C:\Users\helez\appAdmin-Artvinca\functions\node_modules\express\lib\router\layer.js:71:5) at trim_prefix (C:\Users\helez\appAdmin-Artvinca\functions\node_modules\express\lib\router\index.js:326:13) at C:\Users\helez\appAdmin-Artvinca\functions\node_modules\express\lib\router\index.js:286:9 at Function.process_params (C:\Users\helez\appAdmin-Artvinca\functions\node_modules\express\lib\router\index.js:346:12) at next (C:\Users\helez\appAdmin-Artvinca\functions\node_modules\express\lib\router\index.js:280:10) at Layer.handle_error (C:\Users\helez\appAdmin-Artvinca\functions\node_modules\express\lib\router\layer.js:67:12) at trim_prefix (C:\Users\helez\appAdmin-Artvinca\functions\node_modules\express\lib\router\index.js:326:13) at C:\Users\helez\appAdmin-Artvinca\functions\node_modules\express\lib\router\index.js:286:9 at Function.process_params (C:\Users\helez\appAdmin-Artvinca\functions\node_modules\express\lib\router\index.js:346:12)
原因分析
报错指向app.js第118行的req.session.isLoggedIn,说明**req.session在POST请求中为undefined**,核心原因包括:
- Firebase Hosting转发请求到Functions时,未正确传递会话Cookie(
__session),导致会话无法被识别。 - 跨域配置冲突:同时使用
cors中间件和手动设置CORS头,导致浏览器拒绝在跨域请求中携带Cookie。 - 会话Cookie的生产环境属性缺失:未设置
Secure、SameSite等生产环境必需的Cookie属性,浏览器拦截Cookie。 - 错误处理中未做安全判断,直接访问
req.session.isLoggedIn导致报错。
解决方案
1. 配置Firebase Hosting转发会话Cookie
修改项目根目录的firebase.json,确保Hosting转发请求时携带__session Cookie:
{ "hosting": { "rewrites": [ { "source": "**", "function": "app", "headers": { "Cookie": "$request.cookie.__session" } } ] } }
2. 修复会话配置的生产环境适配
更新app.js中的session配置,添加生产环境必需的Cookie属性:
app.use(session({ name: "__session", secret: process.env.SESSION_SECRET || 'my-secret', // 建议用环境变量存储密钥 resave: false, saveUninitialized: false, store: store, cookie: { secure: process.env.NODE_ENV === 'production', // 生产环境启用Secure(HTTPS下生效) httpOnly: true, sameSite: process.env.NODE_ENV === 'production' ? 'strict' : 'lax', // 生产环境严格限制跨域Cookie maxAge: 24 * 60 * 60 * 1000 // 设置Cookie有效期为1天 } }))
3. 统一CORS配置,避免冲突
移除手动设置的CORS头代码,保留cors中间件并开启凭证支持:
// 移除以下手动设置CORS的代码 /* app.use((req, res, next) => { res.setHeader('Access-Control-Allow-Origin', '*'); res.setHeader('Access-Control-Allow-Method', 'GET, POST, PUT, PATCH, DELETE'); res.setHeader('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization'); next(); }); */ // 修改cors配置,允许携带凭证 app.use(cors({ origin: true, credentials: true }));
4. 错误处理中增加安全判断
修改app.js中的错误处理中间件,使用可选链操作符避免req.session为undefined时的报错:
app.use((error, req, res, next) => { res.status(500).render('500', { pageTitle: 'Error!', path: '/500', isAuthenticated: req.session?.isLoggedIn || false }); });
同时更新res.locals的设置:
app.use((req, res, next) => { res.locals.isAuthenticated = req.session?.isLoggedIn || false; res.locals.csrfToken = req.csrfToken(); console.log("locals", res.locals) next(); });
5. 确保生产环境MongoDB连接正常
- 通过Firebase CLI设置环境变量:
firebase functions:config:set mongodb.uri="你的MongoDB连接字符串",并在app.js中读取:
const MONGODB_URİ = functions.config().mongodb.uri || process.env.MONGO_DB;
- 完善MongoDB连接日志,方便排查问题:
mongoose.connect(MONGODB_URİ) .then(() => { console.log('MongoDB连接成功'); }) .catch(err => { console.error('MongoDB连接失败:', err); });
内容的提问来源于stack exchange,提问作者albanya
相关产品推荐
相关产品推荐

