react-native-google-signin / google-signin

Google Sign-in for your React Native applications
https://react-native-google-signin.github.io/
MIT License
3.24k stars 882 forks source link

supabase signInWithIdToken not working: Nonces mismatch #1176

Closed saadHeisentech closed 1 day ago

saadHeisentech commented 1 year ago

edit: this is now available - see https://github.com/react-native-google-signin/google-signin/issues/1176#issuecomment-2461003447

// using this library for decoding
import jwtDecode from 'jwt-decode'

const handleLogin = async () => {
    setLoading(true);
    try {
      await GoogleSignin.hasPlayServices();
      const u = await GoogleSignin.signIn();
      // get the nonce value
      const nonce = jwtDecode<any>(u.idToken!);
      const { nonce: nonceVal } = nonce!;
      // login to supabase
      const { data, error } = await supabase.auth.signInWithIdToken({
        provider: 'google',
        token: u.idToken!,
        nonce: nonceVal,
      });
      console.log('supabase data:', data);
      if (error) {
        console.log('Supabase error:', error);
      }
      if (data.user) {
        // do something
      }
    } catch (err) {
      console.log(err);
    } finally {
      setLoading(false);
    }
  };
jason-dubon commented 1 year ago

Did you try to also pass the access token in the signInWithIdToken function?

He1nr1chK commented 1 year ago

Did you try to also pass the access token in the signInWithIdToken function?

Passing access_token along with id_token does not solve the error: [AuthApiError: Passed nonce and nonce in id_token should either both exist or not.]

sunnyysetia commented 1 year ago

+1 having the same issue :(

furkand commented 1 year ago

is there any solution I am having exactly same issue

timdobranski commented 1 year ago

I've been blocked on this for a while now. My code is nearly identical to the OP. I'm getting the nonce from jwt-decode, but passing it in the signInWithIdToken() call only changes the error from 'Passed nonce and nonce in id_token should either both exist or not' to nonces mismatch. Anyone have any suggestions or solutions?

It seems like the signInWithIdToken() isn't behaving as expected, or I'm missing something.

Eirmas commented 1 year ago

To my understanding Supabase expects the nonce to be the decoded version of the nonce present in the ID token received from google, hence why passing the nonce from the ID token doesnt work as it will get its hash and match them for equality. Unfortunately I cannot find any way to get the nonce before its encoded in the ID token. Any ideas?

/** If the ID token contains a `nonce` claim, then the hash of this value is compared to the value in the ID token. */
nonce?: string
timdobranski commented 1 year ago

Hate to say it, but it doesn't look like this will work currently. Supabase requires a nonce if it's in the token, and react native doesn't expose the nonce in its current implementation. Unless I've got something wrong, native signin on iOS with supabase and react-native isn't possible at this time. Either supabase has to modify the endpoint (unlikely) or react-native has to expose the nonce (unlikely any time soon, I assume).

vonovak commented 1 year ago

Hello and thanks for reporting, ~I did not test this, and it may not work, but~ the next version of the google sign in library obtainable for sponsors here allows passing custom nonce. Maybe that will work. edit: it only allows that on Android

edit2: I tested this and it works, can be used like this:

 const nonce = Crypto.randomUUID()
 const hashedNonce = await digestStringAsync(CryptoDigestAlgorithm.SHA256, nonce)
 const userInfo = await GoogleOneTapSignIn.signIn({
      webClientId,
      nonce: hashedNonce,
    })

Thank you 🙂

vonovak commented 1 year ago

quick update: passing custom nonce works as outlined in the post above, for Android.

For iOS, I confirm that a valid idToken for supabase can be obtained using https://docs.expo.dev/versions/latest/sdk/auth-session/ (edit: no need to use any of the deprecated APIs)

edit2: the underlying native sdk for iOS didn't expose the ability to set custom nonce. Hence rn-google sign in could not expose it either.

related issue: https://github.com/supabase/gotrue/issues/1205#issuecomment-1730933104

sonipranjal commented 1 year ago

Facing the same issue AuthApiError: Passed nonce and nonce in id_token should either both exist or not.

Any workaround?

sonipranjal commented 1 year ago

Expo auth session for Google auth is deprecated: https://docs.expo.dev/versions/latest/sdk/auth-session/#googleauthrequestconfig

sonipranjal commented 1 year ago

Hi everyone, I got it working by using the browser

Made a gist for everyone who is struggling to solve this:

https://gist.github.com/sonipranjal/f4a66f35924ede2e2f4a8d5b66199857

codypl commented 1 year ago

I am having the same problem, it seems like @react-native-google-signin/google-signin and supabase are not compatible because there is currently no way to get the nonce value expected by supabase signInWithIdToken method

alexandreandriesse commented 1 year ago

Same problem here, the library is useless if we can't get, or pass, the nonce value...

erdemgonul commented 1 year ago

same problem here...

vonovak commented 1 year ago

hello everyone, I'm going to lock this discussion because there's nothing new that can be added to it at this point.

To summarize (basically repeating this comment): to provide custom nonce:

on Android, you need to use one-tap sign in which is available for sponsors. on iOS, it can be implemented using expo's authSession (it's not trivial, but can be done - you can hire me if you're unsure how to do it), or using the workaround posted above.

Thank you! 🙂

vonovak commented 9 months ago

Hello, if anyone's interested in how to do this properly on iOS, including custom nonce, with expo-auth-session, the code is here. However, please note it's not publicly available, but you can get access to it if you sponsor this project, as described in the docs.

My PR to allow custom nonce in AppAuth is merged, but now we need to wait for the work to be released (by AppAuth maintainers) and integrated into the Google Sign In SDK (I'll do that part). https://github.com/openid/AppAuth-iOS/pull/788

davidivad96 commented 9 months ago

There's an option in the Google provider configuration in Supabase that allows to skip these nonce checks:

Screenshot 2024-02-24 at 18 14 18

This is indeed useful for this specific situation where we don't have access to the nonce used (iOS app)

bjollans commented 9 months ago

I got this working for myself using react-native-app-auth. See this gist for a minimal working solution.

Maintainer edit: please note this approach skips the nonce. Not using nonce is not recommended for security reasons.

danielkv commented 9 months ago

There's an option in the Google provider configuration in Supabase that allows to skip these nonce checks:

Screenshot 2024-02-24 at 18 14 18

This is indeed useful for this specific situation where we don't have access to the nonce used (iOS app)

That works in production, but locally we don't have this option.

abhishekmg commented 8 months ago

Any solutions without skipping nonce checks ?

jonassvalin commented 7 months ago

@vonovak Hi, thanks for all the work 👋

It is my understanding that AppAuth-iOS v1.7.X has been released which includes the custom nonce fix: https://github.com/openid/AppAuth-iOS/releases

Is there anything blocking that from being integrated now or is it just a matter of time/prioritisation?

vonovak commented 7 months ago

hi @jonassvalin, You're welcome! It's the matter of getting this https://github.com/google/GoogleSignIn-iOS/pull/402 reviewed (I expect I'll be asked to do some changes), merged and released. Then I'll be able to integrate it into this lib.

In the mean time, the best workaround is in https://github.com/react-native-google-signin/google-signin/issues/1176#issuecomment-1957644469

evelant commented 6 months ago

@danielkv I don't think it's documented anywhere but you can skip nonce checks locally via supabase/config.toml for example:

[auth.external.google]
enabled = true
client_id = "env(GOOGLE_OAUTH_CLIENT_ID)"
secret = "env(GOOGLE_OAUTH_CLIENT_SECRET)"
redirect_uri = "env(OAUTH_CALLBACK_URL)"
skip_nonce_check = true

This works for me (after a supabase stop and supabase start) when I test google sign-in in development.

Battjmo commented 5 months ago

@danielkv I don't think it's documented anywhere but you can skip nonce checks locally via supabase/config.toml for example:

[auth.external.google]
enabled = true
client_id = "env(GOOGLE_OAUTH_CLIENT_ID)"
secret = "env(GOOGLE_OAUTH_CLIENT_SECRET)"
redirect_uri = "env(OAUTH_CALLBACK_URL)"
skip_nonce_check = true

This works for me (after a supabase stop and supabase start) when I test google sign-in in development.

I wanted so badly for this to work, but it doesn't for me. Have you tried it on iOS?

evelant commented 5 months ago

Works fine for me on the ios simulator

Battjmo commented 5 months ago

In a browser or as an app? I'm using an iOS Client ID so there's no secret or redirect URI, not sure if that matters. But yeah still getting the nonce error. Blugh.

daniel-xyz commented 4 months ago

@Battjmo I had to update the supabase CLI and pull the latest docker images to make it work, since skip_nonce_check got added just recently. Not sure if it was necessary to do both, but it works now.

elyobo commented 2 months ago

Merged!

Hello, if anyone's interested in how to do this properly on iOS, including custom nonce, with expo-auth-session, the code is here. However, please note it's not publicly available, but you can get access to it if you sponsor this project, as described in the docs.

My PR to allow custom nonce in AppAuth is merged, but now we need to wait for the work to be released (by AppAuth maintainers) and integrated into the Google Sign In SDK (I'll do that part). openid/AppAuth-iOS#788

vonovak commented 2 months ago

Hello, thanks for commenting. I'm well aware of the merge, it took me almost a year to get the feature integrated into Google's repos 😅🥵. It's still not released though and I want to use the official release of the sdk. We need to wait a bit more. Thank you

elyobo commented 2 months ago

Sorry, wasn't intending to nag you, just celebrating 🎉

vonovak commented 3 weeks ago

Hello all, quick update: the work that I did in AppAuth and Google Sign in for iOS to enable custom nonce is now released. You can specify custom nonce without having to disable the nonce check in Supabase. That means you don't need to compromise on security. Custom nonce is available in the One-tap module.

I'm going to add some docs for this later but for now, if you use Supabase and Expo you can generate a custom nonce and then pass its digest to this package:

import { digestStringAsync, randomUUID } from 'expo-crypto'

export const getNonce = async () => {
  // nonce goes to Supabase's signInWithIdToken()
  const nonce = randomUUID()
  // nonceDigest goes to react-native-google-signin
  const nonceDigest = await digestStringAsync(CryptoDigestAlgorithm.SHA256, nonce)
  return { nonce, nonceDigest }
}

Thank you!

vonovak commented 1 day ago

Hello 👋 , documentation is now available: https://react-native-google-signin.github.io/docs/security

With that, I'm closing the issue, Thank you! 🙂