mirror of
https://github.com/supabase/supabase.git
synced 2026-10-10 20:05:06 +03:00
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:
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:
|
||||
|
||||
|
||||
Reference in new issue
Block a user