Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Express session does not work with Firebase Hosting

When I have the following, sessions are persisted and the page counts the number of visits.

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!");
   }
});

However, when I remove the app.listen(3000, ...) and instead run in localhost through the command firebase serve in the CLI, sessions are not persisted.

I also tried running on production environment through firebase deploy but, again, sessions are not persisted.

I have tried multiple options on the app.use(session({ and I believe the solution might be there.

Any recommendations?

UPDATE

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 }
}));
like image 823
rgoncalv Avatar asked Jul 01 '18 00:07

rgoncalv


People also ask

Can you use Express with Firebase?

Use a web framework. You can use web frameworks, like Express. js, in Cloud Functions to serve your app's dynamic content and write complex web apps more easily. Firebase Hosting also supports HTTPS requests to Cloud Run containers.

How to store session in Express?

Information associated with the client is stored on the server linked to this ID. We will need the Express-session, so install it using the following code. We will put the session and cookie-parser middleware in place. In this example, we will use the default store for storing sessions, i.e., MemoryStore.

Why Express-session is used?

Express-session - an HTTP server-side framework used to create and manage a session middleware. This tutorial is all about sessions. Thus Express-session library will be the main focus. Cookie-parser - used to parse cookie header to store data on the browser whenever a session is established on the server-side.

What is secret in Express-session?

A session secret is a key used for encrypting cookies. Application developers often set it to a weak key during development, and don't fix it during production. This article explains how such a weak key can be cracked, and how that cracked key can be used to gain control of the server that hosts the application.


1 Answers

I will suggest something, instead of using this FirestoreStore, I will suggest you use this FirebaseStore.

And I noticed you're using Express, so you might want to check the usage below:

Express

NOTE: In Express 4 express-session must be passed to the function connect-session-firebase exports in order to extend 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
  }));

And you might also want to really consider the Security provided by that dependency

If you use a publicly available Firebase Database, please set proper rules:

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

You can get to read more about Firebase rules and connect-session-firebase

like image 190
antzshrek Avatar answered Oct 07 '22 14:10

antzshrek