Skip to content

Question: Correct OAuth2 flow + client_secret handling for Flutter Windows desktop with googleapis_auth #734

@rprudchenko

Description

@rprudchenko

I'm building a Flutter Windows desktop application that needs to authenticate users
with Google and access Google Drive via the googleapis package. I'm using googleapis_auth for the auth layer. We currently fetch clientId and clientSecret from our own backend REST endpoint and pass them to obtainAccessCredentialsViaUserConsent(). This is insecure and we need to remove this pattern before our beta release.

Questions:

  1. Is it acceptable to embed client_secret in a Flutter Windows binary? Per RFC 8252 §8.5, desktop apps are "public clients" that cannot keep secrets. Google's OAuth2 team has publicly stated they don't expect these secrets to stay secret. However, obtainAccessCredentialsViaUserConsent requires a ClientId(id, secret) object - is passing an empty string for secret acceptable for a "Desktop app" OAuth client type?
  2. Does googleapis_auth support PKCE for the loopback redirect flow on Windows? On Windows there are no OS-level redirect mechanisms (unlike Android Intents), so the correct approach per RFC 8252 is loopback (127.0.0.1). Does obtainAccessCredentialsViaUserConsent implement PKCE? If not, is there a recommended way to add it?
  3. Secure token storage on Windows: after obtaining credentials via googleapis_auth, what is the recommended way to persist and reload them securely on Windows (Credential Locker)? Should we use flutter_secure_storage with the AccessCredentials object?

Minimal code:

import 'package:google_sign_in/google_sign_in.dart';
import 'package:googleapis/drive/v3.dart' as google_api;
import 'package:googleapis_auth/auth_io.dart';
import 'package:googleapis_auth/googleapis_auth.dart' as google_auth;
import 'package:http/http.dart' as http;

final clientId = ClientId('MY_CLIENT_ID', 'MY_CLIENT_SECRET');
final scopes = [DriveApi.driveFileScope];
final httpClient = http.Client();

final client = await obtainAccessCredentialsViaUserConsent(
    clientId,
    scopes,
    httpClient,
    (url) {
		/// Proceed auth flow via browser.
    },
),

Environment:

  • extension_google_sign_in_as_googleapis_auth: 2.0.13
  • googleapis: 14.0.0
  • Flutter: 3.41.4, Windows desktop
  • OAuth client type in GCP Console: Desktop app

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions