Session: Manage session with nextJS and Firebase Cloud Functions

Created on 4 Sep 2017  路  4Comments  路  Source: expressjs/session

Hi,
i want use the express-session in my nextJS app on firebase cloud functions.
This is my code:

const server = express();
server.use(helmet());
server.set('trust proxy', 1);
server.use(bodyParser.json());
server.use(bodyParser.urlencoded({ extended: true }));
server.use(
  session({
    store: new FirebaseSession({  // <== connect-session-firebase
      database: firebase.database(),
    }),
    name: 'ws_auth',
    secret: 'mysecret',
    secure: true,
    httpOnly: true,
    resave: false,
    rolling: true,
    cookie: { maxAge: 604800000 }, // week
    saveUninitialized: false,
    signed: true,
  })
);

server.use(function(q, r, n) {
  console.log('after session:', q.session);
  n();
});

server.post('/api/login', async (req, res) => {
  if (!req.body) return res.sendStatus(400);
  if (!req.session) return res.sendStatus(400);

  try {
    const token = req.body.token;
    const decodedToken = await firebase.auth().verifyIdToken(token);

    console.log('LOGIN SESSION', req.session);

    req.session.decodedToken = decodedToken;
    res.json({ status: true, decodedToken });
  } catch (err) {
    res.json({ err });
    console.log('ERROR', err);
  }
});

server.post('/api/logout', (req, res) => {
  req.session.decodedToken = null;
  res.json({ status: true });
});

server.get('*', (req, res) => {
  console.log('APP', req.session);
  handle(req, res);
});

export let app = functions.https.onRequest(async (req, res) => {
  await nextApp.prepare();
  server(req, res);
});

At the first time the session is created and after login the decodeToken is added to the session in my firebase database.
On my browser the session is created with the right id.

after session: Session {
  cookie: 
   { path: '/',
     _expires: 2017-09-11T10:32:42.976Z,
     originalMaxAge: 604800000,
     httpOnly: true } }

------------------------------------------------------

LOGIN SESSION Session {
  cookie: 
   { path: '/',
     _expires: 2017-09-11T10:32:42.976Z,
     originalMaxAge: 604800000,
     httpOnly: true } }

When i send a new request i have this LOG:

after session: Session {
  cookie: 
   { path: '/',
     _expires: 2017-09-11T10:34:06.277Z,
     originalMaxAge: 604800000,
     httpOnly: true } }

------------------------------------------------------

APP Session {
  cookie: 
   { path: '/',
     _expires: 2017-09-11T10:34:06.277Z,
     originalMaxAge: 604800000,
     httpOnly: true } }

The session not have the decodeToken info, the client repeat the login and i see this LOG:

after session: Session {
  cookie: 
   { path: '/',
     _expires: 2017-09-11T10:32:42.979Z,
     originalMaxAge: 604800000,
     httpOnly: true },
  decodedToken: 
   { // my info... } }

------------------------------------------------------

LOGIN SESSION Session {
  cookie: 
   { path: '/',
     _expires: 2017-09-11T10:32:42.979Z,
     originalMaxAge: 604800000,
     httpOnly: true },
  decodedToken: 
   { // my info... } }

Now the session have the decodeToken info...i don't understand because not pass the right session for every request...

question

Most helpful comment

For others who have the same issue, the fix is to use '__name' as the name instead of the default name 'connect.sid'

app.use(session({
  ...
  name: '__session'
}));

All 4 comments

For others who have the same issue, the fix is to use '__name' as the name instead of the default name 'connect.sid'

app.use(session({
  ...
  name: '__session'
}));

For anyone else having this issue, I also had to execute req.session.save() inside of the login path for the decoded token to persist.

server.post('/api/login', async (req, res) => {
  if (!req.body || !req.session) {
    return res.json({ status: 400, err: 'Missing request token' })
  }

  try {
    const decodedToken = await admin.auth().verifyIdToken(req.body.token)

    req.session.decodedToken = decodedToken

    await new Promise((resolve, reject) => 
        req.session.save(err => (err ? reject(err) : resolve())))

    return res.json({ status: 200, decodedToken })
  } catch (err) {
    return res.json({ status: 400, err })
  }
})

@sarovin @agentilela How do you handle req.session on client-side navigation? For me, req.session is only available in getInitialProps on the server-rendered requests.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

renehauck picture renehauck  路  16Comments

gk0us picture gk0us  路  18Comments

neutron92 picture neutron92  路  20Comments

G-Adams picture G-Adams  路  16Comments

azfar picture azfar  路  14Comments