firebase / firebase-js-sdk

Firebase Javascript SDK
https://firebase.google.com/docs/web/setup
Other
4.82k stars 885 forks source link

Nonce is missing in the request signInWithCredential, OIDC Firebase IDP #7957

Open atomassoni opened 8 months ago

atomassoni commented 8 months ago

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.

google-oss-bot commented 8 months ago

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

atomassoni commented 8 months ago

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.

Litromongo commented 7 months ago

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.

cefitzger1 commented 7 months ago

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.

doiyuki commented 6 months ago

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.