Skip to content

Commit 77593c8

Browse files
Ensure there is always at most one refresh token request at the same time
ref DEV-3054
2 parents 51c09b8 + 675a255 commit 77593c8

File tree

1 file changed

+39
-22
lines changed

1 file changed

+39
-22
lines changed

lib/src/container.dart

Lines changed: 39 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,8 @@ class Authgear implements AuthgearHttpClientDelegate {
240240
Stream<SessionStateChangeEvent> get onSessionStateChange =>
241241
_sessionStateStreamController.stream;
242242

243+
Future<void>? _refreshAccessTokenTask;
244+
243245
String? _accessToken;
244246
@override
245247
String? get accessToken => _accessToken;
@@ -779,32 +781,47 @@ class Authgear implements AuthgearHttpClientDelegate {
779781

780782
@override
781783
Future<void> refreshAccessToken() async {
782-
final refreshToken = _refreshToken;
783-
if (refreshToken == null) {
784-
await _clearSession(SessionStateChangeReason.noToken);
785-
return;
786-
}
784+
doRefreshAccessToken() async {
785+
final refreshToken = _refreshToken;
786+
if (refreshToken == null) {
787+
await _clearSession(SessionStateChangeReason.noToken);
788+
return;
789+
}
787790

788-
String? deviceSecret = await _sharedStorage.getDeviceSecret(name);
791+
String? deviceSecret = await _sharedStorage.getDeviceSecret(name);
789792

790-
final xDeviceInfo = await _getXDeviceInfo();
791-
final tokenRequest = OIDCTokenRequest(
792-
grantType: GrantType.refreshToken,
793-
clientID: clientID,
794-
refreshToken: refreshToken,
795-
xDeviceInfo: xDeviceInfo,
796-
deviceSecret: deviceSecret,
797-
);
793+
final xDeviceInfo = await _getXDeviceInfo();
794+
final tokenRequest = OIDCTokenRequest(
795+
grantType: GrantType.refreshToken,
796+
clientID: clientID,
797+
refreshToken: refreshToken,
798+
xDeviceInfo: xDeviceInfo,
799+
deviceSecret: deviceSecret,
800+
);
801+
try {
802+
final tokenResponse = await _apiClient.sendTokenRequest(tokenRequest);
803+
await _persistTokenResponse(
804+
tokenResponse, SessionStateChangeReason.foundToken);
805+
} catch (e) {
806+
await _handleInvalidGrantException(e);
807+
if (e is OAuthException && e.error == "invalid_grant") {
808+
return;
809+
}
810+
rethrow;
811+
}
812+
}
813+
814+
if (_refreshAccessTokenTask != null) {
815+
return await _refreshAccessTokenTask;
816+
}
817+
final newTask = doRefreshAccessToken();
818+
_refreshAccessTokenTask = newTask;
798819
try {
799-
final tokenResponse = await _apiClient.sendTokenRequest(tokenRequest);
800-
await _persistTokenResponse(
801-
tokenResponse, SessionStateChangeReason.foundToken);
802-
} catch (e) {
803-
await _handleInvalidGrantException(e);
804-
if (e is OAuthException && e.error == "invalid_grant") {
805-
return;
820+
return await newTask;
821+
} finally {
822+
if (_refreshAccessTokenTask == newTask) {
823+
_refreshAccessTokenTask = null;
806824
}
807-
rethrow;
808825
}
809826
}
810827

0 commit comments

Comments
 (0)