-
Notifications
You must be signed in to change notification settings - Fork 38
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make http requests soft logout aware #2027
Comments
My workaround : import 'package:http/http.dart' hide Client;
import 'package:matrix/matrix.dart';
class MatrixRefreshTokenClient extends BaseClient {
MatrixRefreshTokenClient({
required this.inner,
required this.client,
});
final Client client;
final BaseClient inner;
@override
Future<StreamedResponse> send(BaseRequest request) async {
Request? req;
if ( // only refresh if
// we are actually initialized
client.onSync.value != null &&
// the request is to the homeserver rather than e.g. IDP
request.url.host == client.homeserver?.host &&
// the request is authenticated
request.headers
.map((k, v) => MapEntry(k.toLowerCase(), v))
.containsKey('authorization') &&
// and last but not least we're logged in
client.isLogged()) {
try {
await client.ensureNotSoftLoggedOut();
} catch (_) {
}
// in every case ensure we run with the latest bearer token to avoid
// race conditions
finally {
final headers = request.headers;
// hours wasted : unknown :facepalm:
headers.removeWhere((k, _) => k.toLowerCase() == 'authorization');
headers['Authorization'] = 'Bearer ${client.bearerToken!}';
req = Request(request.method, request.url);
req.headers.addAll(headers);
if (request is Request) {
req.bodyBytes = request.bodyBytes;
}
}
}
return inner.send(req ?? request);
}
} Edit: Way cleaner implementation. |
Suggestion to make it even smaller: We implement this as part of the ´unexpectedResponse` method with maybe a start like this: diff --git a/lib/matrix_api_lite/matrix_api.dart b/lib/matrix_api_lite/matrix_api.dart
index 81023e13..a87e65cd 100644
--- a/lib/matrix_api_lite/matrix_api.dart
+++ b/lib/matrix_api_lite/matrix_api.dart
@@ -45,12 +45,21 @@ class MatrixApi extends Api {
set accessToken(String? token) => bearerToken = token;
+ final StreamController<MatrixException> _onUnknownTokenResponse =
+ StreamController.broadcast();
+ Stream<MatrixException> get onUnknownTokenResponse =>
+ _onUnknownTokenResponse.stream;
+
@override
Never unexpectedResponse(http.BaseResponse response, Uint8List body) {
if (response.statusCode >= 400 && response.statusCode < 500) {
final resp = json.decode(utf8.decode(body));
if (resp is Map<String, Object?>) {
- throw MatrixException.fromJson(resp);
+ final exception = MatrixException.fromJson(resp);
+ if (exception.error == MatrixError.M_UNKNOWN_TOKEN) {
+ _onUnknownTokenResponse.add(exception);
+ }
+ throw exception;
}
}
super.unexpectedResponse(response, body); |
But that lacks a functional retry mechanism. I'd highly prefer a high-level implementation which does not even throw an error first. I tried a lot about possible retry mechanisms, ensuring we have a valid token before sending the request was by far the most reliable which never got me logged out by the SDK. |
- implement a `MatrixRefreshTokenClient` to await token refresh before dispatching http requests - improve documentation about soft logout logic - fix dartdoc locations about soft logout Fixes: famedly#2027 Signed-off-by: The one with the braid <[email protected]>
- implement a `MatrixRefreshTokenClient` to await token refresh before dispatching http requests - improve documentation about soft logout logic - fix dartdoc locations about soft logout Fixes: famedly#2027 Signed-off-by: The one with the braid <[email protected]>
Checklist
In which Project did the bug appear?
Other
If you selected "Other" as Project, please enter in which project the bug occurred.
matrix-dart-sdk
On which platform did the bug appear?
Firefox
SDK Version
v0.38.0
Describe the problem caused by this bug
(Note : the bug report form is really cursed.)
The
Client._innerSync
method currently seems to be the only place honoringMatrixError.M_UNKNOWN_TOKEN
withsoft_logout
. As a developer using the SDK, I'd expect all called endpoints to handle a soft log out. The SDK already ships theFixedTimeoutHttpClient
. I'd propose to implement an an additional layer similar to theRetryClient
on SDK side filtering for soft logout responses and retrying after callingClient.onSoftLogout
.As a current workaround, I ship a
RetryClient
on my application side.Steps To Reproduce
Please note this might take a couple of times to retry since usually the
Client.sync
will refresh the access token fast enough.Screenshots or Logs
No response
Security related
No response
The text was updated successfully, but these errors were encountered: