Merge pull request #16090 from supabase/docs/flutter-google-auth

docs: update native auth login code sample for Flutter to use reverse DNS form of the client ID
This commit is contained in:
Greg Richardson authored and GitHub committed 2023-07-31 11:12:58 -06:00
commit 085cea1016
1 file changed
+73 -62
@@ -72,76 +72,87 @@ When the user provides consent, Google issues an identity token (commonly abbrev
If you are building a Flutter app, you can use [flutter_appauth](https://pub.dev/packages/flutter_appauth) package to sign a user into your Supabase project:
````dart
import 'dart:convert';
import 'dart:math';
import 'package:crypto/crypto.dart';
import 'package:flutter_appauth/flutter_appauth.dart';
import 'package:supabase_flutter/supabase_flutter.dart';
// Generate a random string
final rawNonce = generateRandomString();
final hashedNonce = sha256.convert(utf8.encode(rawNonce)).toString();
// Your registered Google client ID here.
// This will be different for iOS and Android
const clientId = 'YOUR_GOODLE_CLIENT_ID';
// bundle ID for iOS, package name for Android here
final packageName = 'io.supabase.example';
/// fixed for google login
final redirectUrl = '$packageName:/google_auth';
/// fixed for google login
const discoveryUrl =
'https://accounts.google.com/.well-known/openid-configuration';
final appAuth = FlutterAppAuth();
// authorize the user by opening the consent page
final result = await appAuth.authorize(
AuthorizationRequest(
clientId,
redirectUrl,
discoveryUrl: discoveryUrl,
nonce: hashedNonce,
scopes: [
'openid',
'email',
],
),
);
if (result == null) {
throw AuthException(
'Could not find AuthorizationResponse after authorizing');
/// Function to generate a random 16 character string.
String _generateRandomString() {
final random = Random.secure();
return base64Url.encode(List<int>.generate(16, (_) => random.nextInt(256)));
}
// Request the access and id token to google
final tokenResponse = await appAuth.token(
TokenRequest(
clientId,
redirectUrl,
authorizationCode: result.authorizationCode,
discoveryUrl: discoveryUrl,
codeVerifier: result.codeVerifier,
nonce: result.nonce,
scopes: [
'openid',
'email',
],
),
);
Future<AuthResponse> signInWithGoogle() {
// Just a random string
final rawNonce = _generateRandomString();
final hashedNonce =
sha256.convert(utf8.encode(rawNonce)).toString();
final idToken = tokenResponse?.idToken;
/// TODO: update the client ID with your own
///
/// Client ID that you registered with Google Cloud.
/// You will have two different values for iOS and Android.
const clientId = 'YOUR_CLIENT_ID_HERE';
if (idToken == null) {
throw AuthException('Could not find idToken from the token response');
/// reverse DNS form of the client ID + `:/` is set as the redirect URL
final redirectUrl = '${clientId.split('.').reversed.join('.')}:/';
/// Fixed value for google login
const discoveryUrl =
'https://accounts.google.com/.well-known/openid-configuration';
final appAuth = FlutterAppAuth();
// authorize the user by opening the consent page
final result = await appAuth.authorize(
AuthorizationRequest(
clientId,
redirectUrl,
discoveryUrl: discoveryUrl,
nonce: hashedNonce,
scopes: [
'openid',
'email',
],
),
);
if (result == null) {
throw 'Could not find AuthorizationResponse after authorizing';
}
// 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 'Could not find idToken from the token response';
}
return supabase.auth.signInWithIdToken(
provider: Provider.google,
idToken: idToken,
accessToken: tokenResponse?.accessToken,
nonce: rawNonce,
);
}
await signInWithIdToken(
provider: Provider.google,
idToken: idToken,
accessToken: tokenResponse?.accessToken,
nonce: rawNonce,
);```
```
In the Supabase JavaScript library, which you can use with web-based native frameworks like React Native or Expo, you can invoke this functionality like so: