【问题标题】:Express session does not work with Firebase HostingExpress 会话不适用于 Firebase 托管
【发布时间】:2018-12-09 16:48:18
【问题描述】:

当我有以下情况时,会话会持续存在并且页面会计算访问次数。

app.set('trust proxy', true)
// The documentation specifies '1' instead of 'true'

app.use(session({
   secret: 'my secret',
   proxy: true,
   resave: false,
   saveUninitialized: true,
   cookie: { secure: false }
}))

app.listen(3000, function(){
   console.log("Server is connected!");
});

app.get("/login", (req, res) => {
   if(req.session.page_views){
       req.session.page_views++;
       res.send("You visited this page " + req.session.page_views + " times");
   } else {
       req.session.page_views = 1;
       res.send("Welcome to this page for the first time!");
   }
});

但是,当我删除 app.listen(3000, ...) 并通过 CLI 中的命令 firebase servelocalhost 中运行时,会话不会持久化。

我还尝试通过firebase deploy 在生产环境中运行,但同样,会话没有持久化。

我在app.use(session({ 上尝试了多个选项,我相信解决方案可能就在那里。

有什么建议吗?

更新

const express = require('express');
const session = require('express-session');
const FirestoreStore = require('firestore-store')(session);
const bodyParser = require('body-parser');

app.use(cookieParser('My secret'));
app.use(bodyParser.urlencoded({ extended: true }));

app.use(session({
    store: new FirestoreStore({
         database: firebase.firestore()
    }),
    secret: 'My secret',
    resave: true,
    saveUninitialized: true,
    cookie: {maxAge : 60000,
             secure: false,
             httpOnly: false }
}));

【问题讨论】:

    标签: javascript firebase express firebase-hosting


    【解决方案1】:

    如果您使用的是 firebase 托管,您不妨使用一个连接器,将您的快速会话与 firebase 连接起来。

    您可以尝试connect-session-firebase 中间件,它将Firebase 数据库存储与当前快速会话集成。这可能会解决您关于会话持久性的问题。

    更新:

    如果您使用 Firebase 托管和云功能,那么您只能设置名称为 __session 的 cookie。您可能必须使用此名称在 Firebase 托管中保留会话。

    app.use(session({
        store: new FirestoreStore({
             database: firebase.firestore()
        }),
        name: '__session',
        secret: 'My secret',
        resave: true,
        saveUninitialized: true,
        cookie: {maxAge : 60000,
                 secure: false,
                 httpOnly: false }
    }));
    

    更多信息:

    【讨论】:

    • 我用过。它真的缺乏商店。我现在可以看到会话保存在 Firebase 数据库中,但是每次我刷新页面时都会创建一个新会话。似乎浏览器无法匹配 cookie 并创建一个新会话。如何解决这个问题?
    • @rgoncalv 在 github 上为它打开一个错误请求并将其链接到您的答案。
    【解决方案2】:

    我会建议一些东西,而不是使用这个FirestoreStore,我会建议你使用这个FirebaseStore

    我注意到您使用的是 Express,因此您可能需要检查以下用法:

    快递

    注意:在 Express 4 中,express-session 必须传递给函数 connect-session-firebase 导出以扩展 express-session.Store:

    const express = require('express');
    const session = require('express-session');
    const FirebaseStore = require('connect-session-firebase')(session);
    const firebase = require('firebase-admin');
    const ref = firebase.initializeApp({
      credential: firebase.credential.cert('path/to/serviceAccountCredentials.json'),
      databaseURL: 'https://databaseName.firebaseio.com'
    });
    
    express()
      .use(session({
        store: new FirebaseStore({
          database: ref.database()
        }),
        secret: 'keyboard cat'
        resave: true,
        saveUninitialized: true
      }));
    

    您可能还想真正考虑该依赖项提供的安全性

    如果您使用公开可用的 Firebase 数据库,请正确设置 规则:

    {
      "rules": {
        ".read": "false",
        ".write": "false",
        "sessions": {
          ".read": "false",
          ".write": "false"
        },
        "some_public_data": {
          ".read": "true",
          ".write": "auth !== null"
        }
      }
    }
    

    您可以阅读有关Firebase rulesconnect-session-firebase 的更多信息

    【讨论】:

    • 我之前使用过它,它将会话保存到实时数据库。虽然同样的问题。然而,在这两种情况下,我都没有将凭据或数据库 URL 放入 initializeApp(),因为我总是通过只需要调用 initializeApp() 来使用我需要的一切(存储、Firestore)和 Admin SDK。我只是按照firebase.google.com/docs/admin/setup#add_firebase_to_your_app 尝试这样做,并且我确实下载了 json 文件,但它似乎无法识别它。 path/to 应该如何格式化?
    • 你能不能试着做一个示例代码(就像计算页面浏览量一样简单)看看你是否可以让它工作?
    猜你喜欢
    • 2018-10-20
    • 2021-09-09
    • 1970-01-01
    • 1970-01-01
    • 2021-09-19
    • 1970-01-01
    • 2020-06-17
    • 2014-06-04
    • 2018-04-12
    相关资源
    最近更新 更多