2

The problem that I am facing is that after setting a Firebase session cookie, I go to another endpoint that needs to be secure, but req cannot find the cookie.

I am following a Firebase tutorial called Manage Session Cookies that describes how to generate a cookie after a user has logged in using the Firebase signInWithEmailAndPassword function. The user idToken is then passed over to a POST request:

First, I am generating a token and sending it to an endpoint:

function signIn() {
  var email = document.getElementById('email').value;
  var password = document.getElementById('password').value;

  firebase.auth().signInWithEmailAndPassword(email, password).catch(function(error) {
    var errorCode = error.code;
    var errorMessage = error.message;

    if (errorCode === 'auth/wrong-password') {
        alert('Wrong password.');
    } else {
        alert(errorMessage);
    }

    document.getElementById('quickstart-sign-in').disabled = false;

  }).then(user => {
    // Get the user's ID token as it is needed to exchange for a session cookie.
    return user.getIdToken().then(idToken => {
      if (firebase.auth().currentUser) {
        $.ajax({
          method: 'POST',
          url: '/login',
          data: {'email':firebase.auth().currentUser.email,idToken},
          success: function(data) {
            //do other things...
          }
        });          
      }      
    });
  })
}

The URL endpoint, which is getting the idToken from the prior POST request, creating a session cookie with createSessionCookie, then setting the cookie using res.cookie('session', sessionCookie, options):

exports.postLogin = (req, res, next) => {

  // Get the ID token passed
  const idToken = req.body.idToken.toString();

  // Set session expiration to 14 days.
  const expiresIn = 60 * 60 * 24 * 14 * 1000;

  var exampleDB = admin.database().ref('exampleDB');
  exampleDB.once('value', function(snapshot) {
    //unrelated things happening...
    //generate randomData...
  }).then(function() {
    admin.auth().createSessionCookie(idToken, {expiresIn})
      .then((sessionCookie) => {
       // Set cookie policy for session cookie.
       const options = {maxAge: expiresIn, httpOnly: true, secure: true};
       res.cookie('session', sessionCookie, options);
       res.status(200).send(randomData).end();
      }, error => {
       res.status(401).send('UNAUTHORIZED REQUEST!');
      });    
  });
};

The problem that I am facing starts here, when I go to another endpoint, /dashboard. The cookie that I had supposedly set cannot be found, and instead I get an error message stating TypeError: Cannot read property 'session' of undefined for my session cookie:

exports.dashboard = (req, res, next) => {
  const sessionCookie = req.cookies.session || '';
  // a bunch of other code around the session cookie that doesn't even get triggered because of the break in req.cookies.session
}

Am I retrieving the cookie incorrectly? Or have I not set the cookie properly? Or is the cookie somehow not being carried over to this new endpoint, /dashboard, from the page on which the POST to /login happens?

After logging the req to /dashboard I see that I have the following in there, but I don't know if it's from another session for something. If it is from Firebase, I don't know how to access it correctly:

  sessionID: 'ublahxARQVljyGRblahPQrei',
  session: 
   Session {
     cookie: 
      { path: '/',
        _expires: null,
        originalMaxAge: null,
        httpOnly: true },
     returnTo: '/dashboard',
     flash: {},
     _csrfSecret: 'r46blahE+kOzblah5==' },
maudulus
  • 10,627
  • 10
  • 78
  • 117

1 Answers1

2

I believe that you need to use the __session cookie.

When using Firebase Hosting together with Cloud Functions or Cloud Run, cookies are generally stripped from incoming requests. source

This has been encountered before in a different form: Firebase Functions : How to store simple cookies to remember an authenticated user

mootrichard
  • 3,581
  • 13
  • 25
  • 1
    and there is great example in official firebase functions samples page on github, with cors usage also - https://github.com/firebase/functions-samples/blob/master/authorized-https-endpoint/functions/index.js – Michał Dziwota Dec 03 '19 at 23:19