feat: enhance oauth flow with json accept header support

This commit is contained in:
Udhay-Adithya
2025-07-23 17:03:36 +05:30
parent baac50f1ba
commit 98417be651
2 changed files with 114 additions and 42 deletions

View File

@@ -10,6 +10,23 @@ http.Client createHttpClientWithNoSSL() {
return IOClient(ioClient);
}
class _JsonAcceptClient extends http.BaseClient {
final http.Client _inner;
_JsonAcceptClient(this._inner);
@override
Future<http.StreamedResponse> send(http.BaseRequest request) {
request.headers['Accept'] = 'application/json';
return _inner.send(request);
}
@override
void close() {
_inner.close();
}
}
class HttpClientManager {
static final HttpClientManager _instance = HttpClientManager._internal();
static const int _maxCancelledRequests = 100;
@@ -60,4 +77,17 @@ class HttpClientManager {
bool hasActiveClient(String requestId) {
return _clients.containsKey(requestId);
}
http.Client createClientWithJsonAccept(
String requestId, {
bool noSSL = false,
}) {
final baseClient = (noSSL && !kIsWeb)
? createHttpClientWithNoSSL()
: http.Client();
final client = _JsonAcceptClient(baseClient);
_clients[requestId] = client;
return client;
}
}

View File

@@ -5,6 +5,7 @@ import 'package:flutter_web_auth_2/flutter_web_auth_2.dart';
import 'package:oauth2/oauth2.dart' as oauth2;
import '../../models/models.dart';
import '../../services/http_client_manager.dart';
Future<oauth2.Client> oAuth2AuthorizationCodeGrantHandler({
required String identifier,
@@ -36,11 +37,17 @@ Future<oauth2.Client> oAuth2AuthorizationCodeGrantHandler({
}
}
// Create a unique request ID for this OAuth flow
final requestId = 'oauth2-${DateTime.now().millisecondsSinceEpoch}';
final httpClientManager = HttpClientManager();
final baseClient = httpClientManager.createClientWithJsonAccept(requestId);
final grant = oauth2.AuthorizationCodeGrant(
identifier,
authorizationEndpoint,
tokenEndpoint,
secret: secret,
httpClient: baseClient,
);
final authorizationUrl = grant.getAuthorizationUrl(
@@ -58,21 +65,26 @@ Future<oauth2.Client> oAuth2AuthorizationCodeGrantHandler({
);
try {
// Use standard oauth2 package for other providers
final client = await grant.handleAuthorizationResponse(
Uri.parse(uri).queryParameters,
);
log('OAuth2 authorization successful, saving credentials');
await credentialsFile.writeAsString(client.credentials.toJson());
log(client.credentials.toJson());
// Clean up the HTTP client
httpClientManager.closeClient(requestId);
return client;
} catch (e) {
log('Error handling authorization response: $e');
log('URI query parameters: ${Uri.parse(uri).queryParameters}');
// Clean up the HTTP client on error
httpClientManager.closeClient(requestId);
rethrow;
}
}
@@ -102,28 +114,43 @@ Future<oauth2.Client> oAuth2ClientCredentialsGrantHandler({
log("Creating Client with id: ${oauth2Model.clientId}");
log("Creating Client with sec: ${oauth2Model.clientSecret}");
// Otherwise, perform the client credentials grant
final client = await oauth2.clientCredentialsGrant(
Uri.parse(oauth2Model.accessTokenUrl),
oauth2Model.clientId,
oauth2Model.clientSecret,
scopes: oauth2Model.scope != null ? [oauth2Model.scope!] : null,
basicAuth: false,
);
log("Created Client with id: ${client.identifier}");
log("Created Client with sec: ${client.secret}");
log("Created Client with sec: ${client.credentials.toJson()}");
log('Successfully authenticated via client credentials grant');
// Create a unique request ID for this OAuth flow
final requestId = 'oauth2-client-${DateTime.now().millisecondsSinceEpoch}';
final httpClientManager = HttpClientManager();
final baseClient = httpClientManager.createClientWithJsonAccept(requestId);
try {
await credentialsFile.writeAsString(client.credentials.toJson());
log('Saved credentials to file');
} catch (e) {
log('Failed to save credentials: $e');
}
// Otherwise, perform the client credentials grant
final client = await oauth2.clientCredentialsGrant(
Uri.parse(oauth2Model.accessTokenUrl),
oauth2Model.clientId,
oauth2Model.clientSecret,
scopes: oauth2Model.scope != null ? [oauth2Model.scope!] : null,
basicAuth: false,
httpClient: baseClient,
);
log("Created Client with id: ${client.identifier}");
log("Created Client with sec: ${client.secret}");
log("Created Client with sec: ${client.credentials.toJson()}");
return client;
log('Successfully authenticated via client credentials grant');
try {
await credentialsFile.writeAsString(client.credentials.toJson());
log('Saved credentials to file');
} catch (e) {
log('Failed to save credentials: $e');
}
// Clean up the HTTP client
httpClientManager.closeClient(requestId);
return client;
} catch (e) {
// Clean up the HTTP client on error
httpClientManager.closeClient(requestId);
rethrow;
}
}
Future<oauth2.Client> oAuth2ResourceOwnerPasswordGrantHandler({
@@ -155,28 +182,43 @@ Future<oauth2.Client> oAuth2ResourceOwnerPasswordGrantHandler({
log("Creating Client with id: ${oauth2Model.clientId}");
log("Creating Client with sec: ${oauth2Model.clientSecret}");
// Otherwise, perform the owner password grant
final client = await oauth2.resourceOwnerPasswordGrant(
Uri.parse(oauth2Model.accessTokenUrl),
oauth2Model.username!,
oauth2Model.password!,
identifier: oauth2Model.clientId,
secret: oauth2Model.clientSecret,
scopes: oauth2Model.scope != null ? [oauth2Model.scope!] : null,
basicAuth: false,
);
log("Created Client with id: ${client.identifier}");
log("Created Client with sec: ${client.secret}");
log("Created Client with sec: ${client.credentials.toJson()}");
log('Successfully authenticated via client credentials grant');
// Create a unique request ID for this OAuth flow
final requestId = 'oauth2-password-${DateTime.now().millisecondsSinceEpoch}';
final httpClientManager = HttpClientManager();
final baseClient = httpClientManager.createClientWithJsonAccept(requestId);
try {
await credentialsFile.writeAsString(client.credentials.toJson());
log('Saved credentials to file');
} catch (e) {
log('Failed to save credentials: $e');
}
// Otherwise, perform the owner password grant
final client = await oauth2.resourceOwnerPasswordGrant(
Uri.parse(oauth2Model.accessTokenUrl),
oauth2Model.username!,
oauth2Model.password!,
identifier: oauth2Model.clientId,
secret: oauth2Model.clientSecret,
scopes: oauth2Model.scope != null ? [oauth2Model.scope!] : null,
basicAuth: false,
httpClient: baseClient,
);
log("Created Client with id: ${client.identifier}");
log("Created Client with sec: ${client.secret}");
log("Created Client with sec: ${client.credentials.toJson()}");
return client;
log('Successfully authenticated via client credentials grant');
try {
await credentialsFile.writeAsString(client.credentials.toJson());
log('Saved credentials to file');
} catch (e) {
log('Failed to save credentials: $e');
}
// Clean up the HTTP client
httpClientManager.closeClient(requestId);
return client;
} catch (e) {
// Clean up the HTTP client on error
httpClientManager.closeClient(requestId);
rethrow;
}
}