ExportXMLWordPrintable

      Since the MetaBrainz authentication migration, the OAuth server rotates refresh tokens: each successful token refresh consumes the old refresh token and returns a new one in the response, revoking the previous token server-side (single-use rotation).

      Picard's OAuthManager.on_refresh_access_token_finished() (picard/oauth.py) only stores the new access_token from the refresh response and ignores the returned refresh_token. As a result, after the access token expires (expires_in is 3600s / 1 hour), the next refresh sends the now-revoked refresh token, the server responds with HTTP 400 ("'refresh_token' in request was already revoked"), and Picard calls forget_refresh_token() and logs the user out.

      Symptom: The user is asked to log in again on almost every launch, with the failure appearing after a delay matching the ~1-hour access token lifetime.

      Log excerpt:
          E: oauth.on_refresh_access_token_finished: OAuth: access_token refresh failed:
             {"error": "invalid_request", "error_description": "'refresh_token' in request was already revoked."}
          W: OAuth: refresh token is no longer valid, logging out

      Fix: Persist the rotated refresh_token when the token endpoint returns one on refresh (preserving the existing granted scopes). A live token response confirms the server returns a refresh_token field (mebr_...) alongside access_token and expires_in: 3600.

            Assignee:
            Zas
            Reporter:
            Zas
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:

                Version Package
                3.0.0rc2