matrix-org / matrix-authentication-service

OAuth2.0 + OpenID Provider for Matrix Homeservers
https://matrix-org.github.io/matrix-authentication-service/
Apache License 2.0
107 stars 30 forks source link

Refresh token request should be idempotent #2795

Open sandhose opened 2 months ago

sandhose commented 2 months ago

It can happen that a refresh token use works on the server side, but then the response never comes back to the client.

This usually means that the client gets logged out, as their old refresh token isn't valid anymore, and they don't have the new one.

One way clients could work around this would be to redo a authz grant with the same device ID, but this impractical in many situations.

To avoid this problem, we should make the refresh token grant idempotent. This means we should track whether access tokens are used or not, and allow re-using an access token if neither the new access token nor the new refresh token were used.

kegsay commented 2 months ago

This is particularly bad on mobile devices / devices which can be suspended (e.g laptops overnight) because often what happens is any in-flight network requests are frozen, timing out when the device is unsuspended. If the refresh request reached the server before the request was frozen, then this will result in a logout due to this issue.

wrenix commented 1 month ago

Edit/ Final: my problem is solved on client side.


Oh this is the reason why my phone get logout every night Edit: Hmm is just an element-x (Android) Problem not an element-web Edit2: or it has just that client this Problem:

2024-06-14T19:54:39.649643Z  WARN elementx: didRefreshTokens() | 
2024-06-14T19:54:39.655009Z DEBUG elementx: Saving new session data with token: '...budj'. Was token valid: true | 
2024-06-14T19:54:39.666580Z DEBUG elementx: Saved new session data with token: '...budj'. | 
2024-06-14T19:54:39.675595Z DEBUG matrix_sdk::http_client: Error while sending request: Api(Server(ClientApi(Error { status_code: 401, body: Standard { kind: UnknownToken { soft_logout: false }, message: "Token is not active" } }))) | crates/matrix-sdk/src/http_client/mod.rs:196 | spans: send{server_versions=[V1_0, V1_1, V1_2, V1_3, V1_4, V1_5] config=RequestConfig { timeout: 30s } request_id="REQ-0" method=GET uri="https://matrix.private.org/_matrix/client/v3/user/@wrenix:private.org/account_data/m.secret_storage.default_key" status=401 response_size="79 B"}
2024-06-14T19:54:40.098556Z ERROR matrix_sdk::client::futures: Token refresh: OIDC refresh_token rejected with invalid grant | crates/matrix-sdk/src/client/futures.rs:146
2024-06-14T19:54:40.098691Z ERROR matrix_sdk::encryption: Couldn't setup and resume recovery Sdk(Http(RefreshToken(Oidc(Oidc(TokenRefresh(Token(Http(HttpError { status: 400, body: Some(ErrorBody { error: InvalidGrant, error_description: Some("The provided access grant is invalid, expired, or revoked.") }) })))))))) | crates/matrix-sdk/src/encryption/mod.rs:1379
2024-06-14T19:54:40.103757Z  WARN elementx: didReceiveAuthError(isSoftLogout=false) | 

I open an issue also there: https://github.com/element-hq/element-x-android/issues/2999#issue-2342111151