firebase-js-sdk icon indicating copy to clipboard operation
firebase-js-sdk copied to clipboard

Using `signInWithRedirect` with an `authDomain` different than the domain of the app does not complete the sign in (and reports no errors)

Open nicolassanmar opened this issue 2 years ago • 15 comments

Operating System

Ubuntu 20.04 LTS

Browser Version

Chrome 119.0.6045.123 / Firefox 119

Firebase SDK Version

10.7.0

Firebase SDK Product:

AppCheck, Auth

Describe your project's tooling

Next.js (React app), using pages router. Deployed on Vercel.

Describe the problem

I'm migrating Firebase signInWithPopup to signInWithRedirect.

If I don't implement the best practices listed here, the login works fine on Chrome (but not on Firefox and Safari as the documentation states). Implementing the Option # 3 of the documentation (which changes the authDomain of Firebase's configuration to point to our servers, and adds a proxy to rewrite the URLs to Firebase's domain), makes this work on all browsers on my dev environment (where I use a real Firebase project, not an emulation).

The issue happens on the staging environment, where I have different deployments (that are deployed on each PR, with unique URLs), that all point to the main staging URL as the authDomain (let's call it "www.staging.com" ). As they are all unique URLs I cannot allow them all in Google's OAuth list, which is the reason they all point to "www.staging.com", instead of "www.randomUrl123.com" (as an example of one of the PR deployments).

Unfortunately, in the PR deployments, the sign in does not succeed on "www.randomUrl123.com". It first redirects to "www.staging.com" as expected, then to Google (to perform auth), and then redirects back to "www.randomUrl123.com", but no sign in happens, and getRedirectResult returns null instead of throwing an error. The browser console is also empty, so I'm not really sure how to debug this.

The reason I'm filing this as a bug is that the console does not report any issues, the browser tab only has requests with statuses 200 or 302, and getRedirectResult returns null instead of an error. I think we should get some kind of error here to help us debug where this sign in attempt failed.

There is no way for me to allow all the possible URLs like "www.randomUrl123.com" on Google's OAuth, so I must find a way to ensure this works through "www.staging.com"

Steps and code to reproduce issue

On signIn button:

const auth = getAuth();
signInWithRedirect(auth, provider); // The provider I'm testing is Google's OAuth

On _app.tsx:

  useEffect(() => {
    ;(async () => {
      const auth = getAuth();
      try {
        const res = await getRedirectResult(auth)
        console.log(res)
      } catch (err) {
        console.log(err)
      }
    })()
  }, [])

On the dev environement, this resolves to the UserCredentialImpl object, but on "www.randomUrl123.com" this always return null, instead of an error (even though the sign in did not succeed).

I confirmed the issue is caused by using an authDomain different from the domain the app is hosted to, as I changed the authDomain on the staging environment to be "www.randomUrl123.com" and the sign in succeeded on "www.randomUrl123.com" . Given what I mentioned above, I would expect to see the following:

  • An error that states sign in could not be completed, and why
  • Why it did not work, and how can we make it succeed (note that I cannot allow all the possible URLs, so there must be a way to make sign in work when redirecting to a different authDomain)

nicolassanmar avatar Nov 29 '23 15:11 nicolassanmar

I couldn't figure out how to label this issue, so I've labeled it for a human to triage. Hang tight.

google-oss-bot avatar Nov 29 '23 15:11 google-oss-bot

@nicolassanmar I have the same issue, this prevents me signing in with Google on localhost for testing my app locally. Temporary workaround that worked for me is using signInWithPopup instead of signInWithRedirect, that method works as expected on localhost too.

rustamli avatar Dec 03 '23 22:12 rustamli

Hi, thank you for filing this issue.

Why it did not work

In your case, “staging.com" is the authDomain, so it is cross origin compared to “www.randomUrl123.com”. This means login cannot succeed because “www.randomUrl123.com” will try to read session storage of “www.staging.com” which is disallowed.

how can we make it succeed

The only to make it succeed is to disable third-party storage partitioning on Chrome. The steps are:

  1. Open Chrome
  2. Visit chrome://flags/#third-party-storage-partitioning
  3. Setting the "Experimental third-party storage partitioning" status to "Disabled"

But, the best practice is to keep all the domains (the authDomain and the app) to be the same origin. One way to do that is to keep "randomapp.com" a top-level domain. Then use "staging.randomapp.com" as authDomain with the main deployment at "randomurl1.randomapp.com". This is just one approach. You can follow any approach to keep everything on the same origin - https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy.

NhienLam avatar Dec 05 '23 00:12 NhienLam

@NhienLam Thanks for your response! Unfortunately, having both deployments under the same top level domain did not work either. I don't want to disable the security configuration in my browser, so disabling third-party storage partitioning is not an option.

Following the best practice, I have "staging.vercel.app" (not the real URL, but real url is under .vercel.app as well ) as the authDomain. If I try to sign in from "randomUrl123.vercel.app" I experience the same issue (no errors, but no sign in).

According to the documentation, "siblings" are not considered as same origin (as they have different hosts: https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy#definition_of_an_origin).

Given this, and given how popular Vercel is, is there really no way of enabling signInWithRedirect on the random URLs that Vercel generates?

nicolassanmar avatar Dec 06 '23 16:12 nicolassanmar

Given this, and given how popular Vercel is, is there really no way of enabling signInWithRedirect on the random URLs that Vercel generates?

Currently, there is no way to do this other than disabling third-party storage partitioning on Chrome. We will make this a feature request and put it on our radar, but we're unable to promise a timeline right now.

NhienLam avatar Dec 18 '23 17:12 NhienLam

Currently, there is no way to do this other than disabling third-party storage partitioning on Chrome. We will make this a feature request and put it on our radar, but we're unable to promise a timeline right now.

@NhienLam Thanks for confirming my suspicions and for considering this as a feature request. I'm eager to see included in the future!

A possible implementation should be to share data from the embedded iframe to the parent using something like window.postMessage()

nicolassanmar avatar Dec 20 '23 16:12 nicolassanmar

@NhienLam any guidance on how to make signInWithRedirect work with localhost for development without disabling the global security feature? This was working fine for us until recently.

jb4e avatar Jan 03 '24 16:01 jb4e

In my case I am trying to setup cicd on web.app with firebase hosting github action. I don't know of a way to feed in the auth domain generated by firebase hosting github action. If I don't feed it properly I am unable to use signInWithRedirect for the pr environment @NhienLam

mrsylerpowers avatar Jan 07 '24 00:01 mrsylerpowers

@jb4e Unfortunately, there's currently no way to make signInWithRedirect work with localhost without disabling third-party storage partitioning.

NhienLam avatar Jan 08 '24 23:01 NhienLam

@mrsylerpowers Could you try setting the authDomain to be location.hostname if it’s in cicd environment?

NhienLam avatar Jan 09 '24 00:01 NhienLam

I can but the authDomain for google authentication doesn't accept wildcards so when trying to sign in it fails image image @NhienLam

mrsylerpowers avatar Jan 10 '24 03:01 mrsylerpowers

@mrsylerpowers can you try adding your redirect url to Authorized redirect URIs and your domain to Authorized JavaScript origins? You can find both under cloud console credentials.

Xiaoshouzi-gh avatar Jan 16 '24 22:01 Xiaoshouzi-gh

Hello @Xiaoshouzi-gh, I can not as I get a new deployed url with each pr that is created. I am using firebase hosting github action which for every deployment creates a new domain for every pr and so as soon as I add it it will be expired. example urls: http://pr-334-prtitleplusextranumbers-332434-mygcpprojectid.web.app http://pr-366-prtitleplusextranumbersextratitle-9812893-mygcpprojectid.web.app

mrsylerpowers avatar Jan 17 '24 03:01 mrsylerpowers