If you're reading this you've probably just discovered that Firebase Auth only authenticates for a single domain, yet you need to share that authen...
For further actions, you may consider blocking this person and/or reporting abuse
We've built a version based on the original post by John Carrol you link above and are struggling with complex logic that is periodically causing logouts for new users. We are using the __sesion token but also making use of the suggested CSRF cookie. Are you aware of any security implications to you having omitted that step recommended by John Carrol in his linked post? I would love to simplify the logic we are using and remove additional steps if they are not required.
John's approach is solid and if implemented correctly should be secure. The above approach I'd call a refinement. The primary improvements here are using a single Firebase session cookie across all domains for stateless JWT authentication and no cross-domain requests.
The CSRF protections should be implemented no matter what, I didn't include that because it seemed out of scope however just making an
httpOnly
__session
cookie and strict a strict single-domain CORS policy on the/auth/*
endpoints would make any XSS attack difficult. The only change I would recommend from his approach would be to pass the CSRF token with a custom HTTP header and not a cookie, but that's splitting hairs.Also if you're not using Firebase session cookies that may be the cause of your users getting randomly logged out.
Thanks for following this up. I'll double check the __session cookie we are assigning, it could very well be that it's not the Firebase session cookie.
Interesting. But wouldn't calling
revokeRefreshTokens(<uid>)
sign the user out of every browser and every device? Not just the browser/device they are trying to sign out of?Yes unfortunately it's a nuke 'em all approach, but alternatively the client could monitor the presence of the
__session
cookie and log the user out client side on each subdomain if it's missing.Updated the last step to show how to revoke a user's authentication across all devices or just the current device.
Interesting approach. At step (I.2) do you suggest POSTing the ID Token inside the http body to app1.domain.com/auth/login? If so, how is it different from POSTing it to a http cloud function directly (possibly hosted on auth.domain.com)?
For your first question, yes I POST the ID token inside the body to
/auth/login
.For your second question, the
/auth/login
endpoint checks and sets a session cookie for that domain, so it needs to be on the same domain. Another minor benefit is that it also avoids potential CORS errors.This looks really great but I understand that with
createSessionCookie()
the maximum expiresIn value you can set is two weeks? That means that users would have to sign again every two weeks correct? It's too bad they don't allow for longer cookies.Perhaps one could do this to extend the cookie, but that would only work if the user is using one of the subdomains more than once every two weeks. 🤔
When the user hits
/auth/status
you can always refresh the token and update the session cookie.Hi! Very interesting post, I have been trying to implement this with 2 Firebase apps from the same project, I am pretty sure that it'll work in production (if both apps run on the same domain) but I am having a lot of problems getting this to run locally. Modern cookie setting for Chrome and most browsers prevent cross-site cookies from going through insecure connections, as of today, there is no way to run the emulators on HTTPS. I tried using self-signed certificates on localhost but the browsers won't allow HTTPS even with that (even with chrome://flags/#allow-insecure-localhost set to enabled in Chrome). At the end all this means that app 1 is setting the cookie, but the browser is never sending it to app 2. Any suggestions? Did you ever got this to work locally?
For local dev it may be easier to add some code to determine if it's running locally and then just faking the session. Perhaps you could set up a reverse proxy in front with nginx. Not sure if it'll work with the firebase local environment but worth a shot.
Are there any code examples for this?
No I never put together a proof of concept example, but honestly I didn't expect so many requests for an example
But why do we need to create custom token, can't we simply validate the requests using verifySessionCookie() each time we get a request?
Two tokens for two different purposes. The custom token that you generate is for client-side authentication using the firebase library in the browser. You can authenticate the visitor using the session cookie for server-side requests, but the firebase client-side library in the browser won't know who the person is.
If you add simple Code to this Idea .. I will be appreciated :)
Thanks for the example. I was wondering if it works for separate domains like domain1.com and domain2.com or if it only works for sub-domains?
For multiple TLDs you'd need use a SAML-style flow.
Have you cooked up any code examples?