google / google/googleapis.dart
Question: Correct OAuth2 flow + client_secret handling for Flutter Windows desktop with googleapis_auth
- Dominant language
- Dart
- Stars
- 419
- Forks
- 136
- Avg merge
- 1h 21m
- Merged PRs (30d)
- 5
Description
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:
```dart
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
Contributor guide
Assessment
This issue has not been assessed yet.