user568551
user568551

Reputation: 449

Firebase google authentication in Chrome Extension - Error getting credential

I'm working on updating a chrome extension to MV3, and therefore I can't use the firebase UI to login any more. What I trying to do is use chrome.identity.launchWebAuthFlow, get the token, create the credential, and sign in with firebase. Here's what I have:

function launchGoogleAuthFlow(interactive) {
  return new Promise((resolve, reject) => {
    console.log('launching webauthflow')
    const manifest = chrome.runtime.getManifest();
    const clientId = encodeURIComponent(manifest.oauth2.client_id);
    const scopes = encodeURIComponent(manifest.oauth2.scopes.join(' '));

let redirectUri = chrome.identity.getRedirectURL();
let nonce = Math.random().toString(36).substring(2, 15)

const authUrl = new URL('https://accounts.google.com/o/oauth2/v2/auth');

  authUrl.searchParams.set('client_id', clientId);
  authUrl.searchParams.set('response_type', 'id_token');
  authUrl.searchParams.set('redirect_uri', redirectUri);
  // Add the OpenID scope. Scopes allow you to access the user’s information.
  authUrl.searchParams.set('scope', 'openid profile email');
  authUrl.searchParams.set('nonce', nonce);
  // Show the consent screen after login.
  authUrl.searchParams.set('prompt', 'consent');


    chrome.identity.launchWebAuthFlow(
      {
        'url': authUrl.href,
        'interactive': interactive
      },
      (redirectedTo) => {
        if (chrome.runtime.lastError) {
          console.log(chrome.runtime.lastError.message);
          resolve(null)
        }
        else {
          let idToken = redirectedTo.substring(redirectedTo.indexOf('id_token=') + 9)
          idToken = idToken.substring(0, idToken.indexOf('&'))
          resolve(idToken)
        }
      }
    )
  })
}

launchGoogleAuthFlow(true).then((token)=>{
        if (token) {
          console.log('token:' + token);
          const credential = GoogleAuthProvider.credential(null, token);
          console.log(credential);
          signInWithCredential(auth, credential).then((result) => {
            showMain();
      document.getElementById('loggedInAs').textContent = result.email;

              console.log("Success!!!")
              console.log(result)
          }).catch((error) => {
              // You can handle errors here
              console.log(error)
          });
      } else {
          console.error('The OAuth token was null');
      }
      }); 
      console.log('finished authflow');
  }

I'm getting prompted to sign in with my google credentials, then in the console I get Failed to load resource: the server responded with a status of 400 () and then the a log from SignInWithCredentials

FirebaseError: Firebase: Unsuccessful check authorization response from Google: {
  "error_description": "Invalid Value"
}
 (auth/invalid-credential).
    at _errorWithCustomMessage (index-6bd8d405.js:453:1)
    at _performFetchWithErrorHandling (index-6bd8d405.js:973:1)
    at async _performSignInRequest (index-6bd8d405.js:988:1)
    at async _signInWithCredential (index-6bd8d405.js:4721:1)

Upvotes: 0

Views: 674

Answers (1)

TDT
TDT

Reputation: 633

In the response_type you are requesting an id_token:

authUrl.searchParams.set('response_type', 'id_token');

So your launchGoogleAuthFlow returns an id_token and that's it what you must give to GoogleAuthProvider.credential. This method expects an a id_token as the first parameter and an a access_token as the second parameter.

So all you have to do is change from:

const credential = GoogleAuthProvider.credential(null, token);

to:

const credential = GoogleAuthProvider.credential(token);

Everything should works fine.


If you may want the access_token you must request response_type=token and remove nonce. Finally you'll need to extract the returned access_token from response URL (your redirectedTo variable) as you did with id_token.


PS: In your code I also noticed that you got scopes from manifest but did not use them while requesting the token.

Upvotes: 1

Related Questions