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

Nonce is missing in the request signInWithCredential, OIDC Firebase IDP

Open atomassoni opened this issue 1 year ago • 6 comments

Operating System

iOS 16+

Browser Version

webview in iOS

Firebase SDK Version

^10.7.1

Firebase SDK Product:

Analytics, Auth, Database, Firestore, Functions, Remote-Config, Storage

Describe your project's tooling

Stencil JS with Capacitor, custom Android and iOS code with web UI

In general, some things are only accessible from the native layer, so we sign into Firebase iOS and Android and then we pass credentials back to the web user interface to log into Firebase there as well. This is done through a simple Capacitor interface. We have Apple, Google, Facebook and Email/Password sign in working in both places.

Describe the problem

I created an OpenID provider on Google Identity provider. Everything is working well on the firebase UI web login. I am able to log in on iOS and get the all the credential info.

Steps and code to reproduce issue

In Swift I get the accessToken and idToken. Nowhere do I set a nonce (I dug around and I couldn't find out how to set one for an OAuthProvider), I am however using the Apple Provider nonce in another part of the app.

       provider = OAuthProvider(providerID: "oidc.my-provider" )
        provider?.getCredentialWith(nil) { credential, error in
                
                if error != nil {
                    print( error?.localizedDescription ?? "oidc sign in error")
                    // Handle error.
                }
                if credential != nil {
                    Auth.auth().signIn(with: credential!) { authResult, error in
                        if error != nil {
                            // Handle error.
                            print(error?.localizedDescription ?? "no credential oidc")
                        }
                        // User is signed in.
                    
                        // IdP data available in authResult.additionalUserInfo.profile.
                        // Access token sent to web view to sign in there
                        let uid = authResult?.user.uid
                        let accessToken = (authResult?.credential as? OAuthCredential)?.accessToken
                        // OAuth ID token can also be retrieved:
                        let idToken = (authResult?.credential as? OAuthCredential)?.idToken
                        self.oidcCall.resolve(["accessToken":accessToken! as String, "idToken":idToken! as String, "uid": uid! as String])
                        
                    }
                } else {
                    self.oidcCall.reject("Sign in Failed")
                }
            
        }

I use a Capacitor function to call the swift code above and it returns a result, and I can see the accessToken and idToken via debugging and via the console log.

    const result = await SworkitMobile.loginWithOIDC();
    console.debug('result', result);
    if (!result) {
      throw new Error('Login not completed');
    }
    const {idToken, accessToken, uid } = result
    const provider = new OAuthProvider('oidc.my-provider');
    const credential = provider.credential({
     // accessToken, have tried with and without access token, makes no difference
      idToken
    });
   
    const auth = getAuth();
    await signInWithCredential(auth, credential)

And then I get an error.

[Error] error with native oauth sign in – FirebaseError: Firebase: Nonce is missing in the request. (auth/missing-or-invalid-nonce).
FirebaseError: Firebase: Nonce is missing in the request. (auth/missing-or-invalid-nonce).

I have tried submitting a rawNonce to provider.credential and I get a different error... But there isn't any documentation on where and how the nonce is being set in the initial sign in. I'm going to move on to Android to see if this same flow works as expected there.

atomassoni avatar Jan 16 '24 21:01 atomassoni

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 Jan 16 '24 21:01 google-oss-bot

I did the same flow on Android 14, com.google.firebase:firebase-auth, com.google.firebase:firebase-bom:28.4.0, (Java from firebase's OIDP provider example with Capacitor passing the token strings and using the same Javascript as above) and get the same error.

atomassoni avatar Jan 17 '24 17:01 atomassoni

Same error here using keycloak id tokens. Keycloak nonce is an uuid value that is sended on oauth token generation and match with returned value of nonce claim. If try to send this nonce, we get error about nonce claim is not a valid sha256 value of provided nonce. We are totally lost about how to solve this problem.

Litromongo avatar Feb 09 '24 10:02 Litromongo

I had the same error/problem using the Web modular API using Auth0 as the provider. I solved it with some trial and error by adding the pendingToken to the credentials sent. "cred" is the credential returned from a signInWithPopup.

        const provider = new OAuthProvider('oidc.auth0');        
        const auth = getAuth();

        const credential = provider.credential({
           idToken: cred.idToken,
           pendingToken: cred.pendingToken,
        });

        signInWithCredential(auth, credential)
        .then((result) => {.......

It's clearly still a problem as the pendingToken expires after a few minutes. But the "Nonce missing" error goes away.

cefitzger1 avatar Feb 14 '24 12:02 cefitzger1

I had the same error/problem using the Web modular API using Auth0 as the provider. I solved it with some trial and error by adding the pendingToken to the credentials sent. "cred" is the credential returned from a signInWithPopup.

        const provider = new OAuthProvider('oidc.auth0');        
        const auth = getAuth();

        const credential = provider.credential({
           idToken: cred.idToken,
           pendingToken: cred.pendingToken,
        });

        signInWithCredential(auth, credential)
        .then((result) => {.......

It's clearly still a problem as the pendingToken expires after a few minutes. But the "Nonce missing" error goes away.

I tried this method. But I got an error↓

Firebase: Error (auth/invalid-credential).

I hope this error will be fixed.

doiyuki avatar Mar 18 '24 03:03 doiyuki