2

As (indirectly) mentioned in the firebase functions docs, https functions are suppose to support manipulating cookies in request / response headers.

If you need to inject middleware dependencies for things like cookie support or CORS, call these within the function.

However, the following HTTPS function returns a response which does not contain a set-cookie header to the client:

functions.https.onRequest(async (request, response) => {
  response.set('access-control-allow-origin', '*');

  response.cookie('TEST COOKIE', 'Success!!!!');

  console.log(response.get('set-cookie'));

  response.json({ status: 'success' });
});

Strangely, the call to console.log(response.get('set-cookie')) shows me that the set-cookie header is set at that point in the function call. So somehow the set-cookie header is being stripped from the response. This certainly seems like firebase functions don't actually support manipulating cookies.

Does anyone have any idea what's going on? I've been trying to figure this out for hours now :(

John
  • 9,249
  • 5
  • 44
  • 76
  • Are you using Cloud Functions with Firebase Hosting. Because in that case this is expected behavior. See https://stackoverflow.com/questions/44929653/firebase-cloud-function-wont-store-cookie-named-other-than-session – Frank van Puffelen Feb 10 '19 at 05:54
  • @FrankvanPuffelen Having read that post, I'm still not sure what is meant by "Firebase hosting with cloud functions". My understanding of firebase hosting is that it is for static content, so I'm not sure how the hosting service could interact with a cloud function. At the moment, my code is being served locally by a dev server. The `functions.https.onRequest()` function is being called via javascript by the client. So I'm going to say no, I'm not using Firebase hosting with cloud functions. (even though, eventually, I expect the SPA to be stored via firebase hosting) Thanks though. – John Feb 10 '19 at 05:59
  • 1
    @FrankvanPuffelen for good measure, I tried following the advice in that post and setting `'Cache-Control'` to `'private'` and changing the cookie name to `__session`. While the `Cache-Control` header is set in the response to the client, the `set-cookie` header is still missing. – John Feb 10 '19 at 06:07
  • @FrankvanPuffelen I finally figured the issue out! Again, thanks for your help! – John Mar 05 '19 at 20:15
  • 1
    Good to hear John! And thanks for self-answering, as this may be very useful for folks who encounter this in the future. – Frank van Puffelen Mar 05 '19 at 22:14

1 Answers1

6

Oh my goodness I figured it out! The firebase function is setting the "set-cookie" header normally. The issue is twofold:

  1. The domain associated with the firebase function is a google domain. You can't set functions for other domains (this is a browser restriction), so a hosted function cannot set a cookie for localhost. It also can't set a cookie for your app domain (which will be different than the domain associated with the function). You'll need to alias the function under your own domain for the ability to set cookies for your own domain (this won't help in development though). See this issue: https://stackoverflow.com/a/51461847/5490505.

  2. This one really annoys me, Google Chrome (v71) automatically hides the "set-cookie" header from the response if its being sent by another domain. If you were attempting to set the cookie for the app's domain, in this case the cookie wouldn't be set anyway, because of browser restrictions. If you don't specify the domain of the cookie however, then the cookie is set for the domain associated with the function, but Google Chrome doesn't show you the header and you have no idea it was set unless you examine your browser's saved cookies. This also gives the appearance that the header isn't even being included in the response, when it is. I thought that the cloud function was stripping the "set-cookie" header, when in fact Google Chrome was stripping the "set-cookie" header. I really don't like this design decision. It made debugging SO hard and I wasted so many more hours on this problem. Firefox behaves as expected, showing you the "set-cookie" header.

I'll also note that, for my purposes, the firebase function is setting a secure, httponly, cookie that is only read by other functions. In this case, having the domain of the cookie be the domain associated with the functions is totally fine (my client side app never looks at the cookie anyway). As such, even though Chrome doesn't show the "set-cookie" header, the cookie is being set and everything is working fine. Another reason why Chrome's design decision is so, so bad.

John
  • 9,249
  • 5
  • 44
  • 76