Closed mreky closed 1 year ago
The Google login package does not support overriding the nonce value, but you can perform native Google login using the AppAuth package like this:
import 'dart:convert';
import 'dart:math';
import 'package:crypto/crypto.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_appauth/flutter_appauth.dart';
Future<AuthResponse> signInWithGoogle(String clientId) {
// Just a random string
final rawNonce = _generateRandomString();
final hashedNonce =
sha256.convert(utf8.encode(rawNonce)).toString();
/// bundle ID of the app
const bundleId = 'com.supabase.authflow';
/// fixed for google login
// const redirectUrl = '$bundleId:/google_auth';
const redirectUrl = '$bundleId:/google_auth';
/// fixed for google login
const discoveryUrl =
'https://accounts.google.com/.well-known/openid-configuration';
// authorize the user by opening the concent page
final result = await appAuth.authorize(
AuthorizationRequest(
clientId,
redirectUrl,
discoveryUrl: discoveryUrl,
nonce: hashedNonce,
scopes: [
'openid',
'email',
],
),
);
if (result == null) {
return;
}
// Request the access and id token to google
final tokenResult = await appAuth.token(
TokenRequest(
clientId,
redirectUrl,
authorizationCode: result.authorizationCode,
discoveryUrl: discoveryUrl,
codeVerifier: result.codeVerifier,
nonce: result.nonce,
scopes: [
'openid',
'email',
],
),
);
final idToken = tokenResult?.idToken;
if (idToken == null) {
throw 'No idToken';
}
return supabase.auth.signInWithIdToken(
provider: Provider.google,
idToken: idToken,
nonce: rawNonce,
);
}
This works as I wanted thank you.
@dshukertjr Hello, I applied the example you mentioned but the AppAuth package opens the browser therefore it would not be native or I am doing something wrong. thank you
@hortigado It opens it in an in app browser, and not open a separate browser app, right? That is the expected result.
In my opinion, as far as the users are concerned, they shouldn't be too worried about whether it's an dialog or an in app browser window. Most users wouldn't care.
If you want to be picky, you could implement Google sign in using google_sign_in package. However, the iOS version of the package does not comply with the Open ID Connect spec, so if you want to implement Google auth on iOS, you would have to use the AppAuth package.
@dshukertjr Thanks for the clarification, although it is true that it is better to open the browser directly. I was interested in the implementation with google_sing_in. You told me that it is possible but I have tried to do it but without success due to the error: "Unacceptable audience in id_token" or I also get a similar one "Passed nonce and nonce in id_token should either both exist or not"
@hortigado on that platform did you get the nonce error? google_sign_in should work on Android.
@dshukertjr On android, it enter the account correctly but supabase gives me that error. I tried creating web client ID (serverClientId) and android (clientId).And I get the same error. I have attached an example of code using a web client that according to another thread worked like this.
const clientId = '340026406803-0je0oa558l95dsvjueinop7a0127p9ti.apps.googleusercontent.com';
GoogleSignIn googleSignIn = GoogleSignIn(serverClientId: clientId);
String? idToken;
await googleSignIn.signIn().then((result) async {
await result?.authentication.then((googleKey) async {
print(googleKey.accessToken);
print(googleKey.idToken);
idToken = googleKey.idToken;
print(googleSignIn.currentUser?.displayName);
}).catchError((err) {
print('inner error');
});
}).catchError((err) {
print('error occured');
});
if (idToken == null) {
throw 'No idToken';
}
return supabase.auth.signInWithIdToken(
provider: Provider.google,
idToken: idToken!,
nonce: rawNonce,
);
@hortigado for Android, you should use the Android client id. Also, where are you getting the raw nonce here? Regardless, you should not pass a nonce in this case.
@dshukertjr I took the raw nonce final rawNonce = _generateRandomString();
from the example you mentioned above. Now I removed it but I still get the same error.
@hortigado That error message means that you haven't added the client ID you are using in the Supabase dashboard. Go to Authentication -> providers -> Google
and add your Android client ID you obtained from the GCP console into Authorized Client IDs
.
@dshukertjr Thank you very much, it worked perfectly. Although I already had it configured; The google_sign_in package took the sha-1 from playstore and that is why it caused the problem.
@hortigado Glad to hear that it worked 🎉 We should probably document this somewhere. Thanks for bearing with us, and happy hacking!
There is option in supabase for google auth.
When I try to log in a user after getting the ID Token with google_sign_in package(I have to use this package because I need to do checks with user email before creating their account). I get the error:
flutter: AuthException(message: Passed nonce and nonce in id_token should either both exist or not., statusCode: 400)
Here is my code to get the ID Token:
`final GoogleSignIn _googleSignIn = GoogleSignIn( scopes: [ 'email', ], ); final GoogleSignInAccount? googleUser = await _googleSignIn.signIn();
Which gives me the ID Token successfully but then when I try to sign in with id token with supabase like this:
await supabase.auth.signInWithIdToken(provider: Provider.google, idToken: idToken);
I get the error mentioned above.