Recover from a rejected refresh token by logging in again#39
Merged
Conversation
Easee refresh tokens are single-use and session-linked. When several requests for the same account hit a 401 at once, they race on the same refresh token; the losers reuse a consumed token, which Easee rejects and which can tear down the session. The previous handler gave up after one failed refresh, so every poll kept returning 401 until the cached token expired (hours), flooding error tracking. Reauthentication now falls back to a full username/password login when the refresh is rejected, as Easee's own guidance recommends, so the client recovers on the next call instead of looping on 401s. A login that fails with invalid credentials still surfaces as InvalidCredentials.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Lost het 401-stormpatroon op dat we in productie zagen op het gedeelde Easee-account (Sentry stekker#2017): bij een afgewezen refresh-token logt de client nu opnieuw in met username/wachtwoord in plaats van te blijven hangen op 401's.
Aanleiding
Sentry stekker#2017:
Connections::ChargePointConnection::RequestFailed: status 401opGET /api/chargers/{id}/state, ~800 events over één account met meerdere laders, in bursts van ~3 tegelijk per refresh-cyclus. Productie-console bevestigde: de credentials zijn geldig (verse login werkt), en het herstelde zichzelf pas zodra de cache-token verliep.Root cause
Easee refresh-tokens zijn single-use en sessie-gebonden (changelog). Wanneer meerdere requests voor hetzelfde account tegelijk een 401 krijgen, racen ze op dezelfde refresh-token: de "verliezers" hergebruiken een al-verbruikte token, die Easee afwijst en die de sessie kan opruimen. De oude
with_error_handlingdeed één refresh en gaf het daarna op (Errors::RequestFailed), waardoor elke poll 401 bleef geven tot de gecachte token verliep (uren) — vandaar de storm.Easee's eigen advies hierbij: "Fall back to username/password authentication when token refresh fails."
Wijziging
with_error_handlingherauthenticeert nu één keer en geeft daarna pas op. De herauthenticatie (reauthenticate!) probeert eerst een refresh en valt bij een afgewezen refresh terug op een volledige login (request_access_token). Daardoor herstelt de client zich op de volgende call i.p.v. te blijven loopen op 401's.InvalidCredentialsopleveren (zodat de caller een echt ongeldig account nog steeds kan loskoppelen).Reproductie
spec/easee/client_spec.rb:RequestFailed.InvalidCredentials.Vervolg
Na merge moet StekkerWeb de gem bumpen (
bundle update stekker_easee, diegithub: "stekker/easee", branch: "main"volgt) om de fix in productie te krijgen. Een per-account lock om de gelijktijdige re-logins verder te beperken kan eventueel later in StekkerWeb via job-serialisatie — niet nodig voor correctheid, want de re-login fallback voorkomt de aanhoudende storm.