Home > Mobile >  Sending a cookie as a response with Firebase Callable Functions
Sending a cookie as a response with Firebase Callable Functions

Time:06-17

I am trying to send a cookie with options set to it as a response using a Firebase callable cloud function (https.onCall). I see in the Firebase docs that this can be done with express: (The below is taken directly form the Firebase docs)

app.post('/sessionLogin', (req, res) => {
  // Get the ID token passed and the CSRF token.
  const idToken = req.body.idToken.toString();
  const csrfToken = req.body.csrfToken.toString();
  // Guard against CSRF attacks.
  if (csrfToken !== req.cookies.csrfToken) {
    res.status(401).send('UNAUTHORIZED REQUEST!');
    return;
  }
  // Set session expiration to 5 days.
  const expiresIn = 60 * 60 * 24 * 5 * 1000;
  // Create the session cookie. This will also verify the ID token in the process.
  // The session cookie will have the same claims as the ID token.
  // To only allow session cookie setting on recent sign-in, auth_time in ID token
  // can be checked to ensure user was recently signed in before creating a session cookie.
  getAuth()
    .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.end(JSON.stringify({ status: 'success' }));
      },
      (error) => {
        res.status(401).send('UNAUTHORIZED REQUEST!');
      }
    );
});

I have implemented the callable function, but I do now know how to attach the options to my cookie string.

The below is my code:


// I want the return type to be a Promise of a cookie object, not a string
export const setCookie = https.onCall(async (context: https.CallableContext): Promise<string> => { 
    try {
        console.log(context);
        const auth: Auth = getAuth();
        const idToken: DecodedIdToken = await auth.verifyIdToken(context.instanceIdToken!); // https://firebase.google.com/docs/auth/admin/verify-id-tokens#web
        console.log("idToken: ", idToken);

        const cookie: string = await auth.createSessionCookie(idToken.uid, { expiresIn: 300000 });
        const options = {
            maxAge: 300000,
            httpOnly: true,
            secure: true,
            sameSite: "strict",
        };
        // res.cookie("session", cookie, options);
        return cookie; // should be assigned to __session cookie with domain .web.app
        // httpOnly=true, secure=true and sameSite=strict set.
    } catch (error) {
        console.log("ERROR FOUND: ", error);
        throw new https.HttpsError("unknown", "Error found in setCookie");
    }
});

Is there any way I can do this using a Callable Firebase Cloud Function? All the documentation and resources I have found require express to send an cookie with Node.

Thanks!

CodePudding user response:

The documentation you're linking to assumes you are writing standard nodejs backend code using express. However, your code is using a callable type function. They are not the same and do not have the same capabilities. Callable functions don't let you set cookies in the response. You can only send a JSON payload back to the client; the SDK handles all of the HTTP headers and they are outside of your control.

Perhaps you should look into using a standard HTTP type function (onRequest), where you do have some control over the headers in the response.

  • Related