nhost-dart icon indicating copy to clipboard operation
nhost-dart copied to clipboard

GQL subscription is using stale JWT after device idle (iOS)

Open shyndman opened this issue 3 years ago • 4 comments

@MaxSchilling has reported that his graphql client is making a request using a stale JWT after the Android device has been off for some amount of time.

After some research, I suspect that Android Doze suspending timers and network connections. When the app resumes, the websocket notices and begins reconnecting with the old JWT, which happens concurrently with the JWT refresh.

I'm confirming now. If correct, the solution is simple, because the way gql_websocket_link is configured gives us control over socket creation, and that API is async — we can keep it waiting for a JWT refresh.

shyndman avatar Jun 07 '21 00:06 shyndman

We had a similar issue with the nhost-js-sdk.

This was our solution there:

https://github.com/nhost/nhost-js-sdk/blob/master/src/Auth.ts#L639-L650

elitan avatar Jun 07 '21 05:06 elitan

Yes! I saw that while porting, and do have questions about that (since people are now building for Flutter Web.)

But in this case, it's not exactly the same issue.

What I'm seeing is Android suspending all network activity while "dozing" (a state that is entered after a few minutes of the screen being off). In this state, application code continues to run, which includes timer callbacks (possibly at a reduced or less exact rate), but network requests never go out (so JWTs don't refresh), and websocket keep alives never come in (leading to socket disconnects+reconnection attempts).

When everything wakes back up, it's in a bad state, because you have a websocket queued up to send its initial payload (which will contain the "current", stale, JWT), and a JWT refresh queued up that whose response won't be received before that payload is sent.

shyndman avatar Jun 07 '21 06:06 shyndman

It actually also occured on iOS

MaxSchilling avatar Jun 07 '21 21:06 MaxSchilling

Ah, well I believe it's even simpler in that case.

iOS standby mode is a lot like Doze from what I've read, but is even stricter. I should be able to repro the issues I've seen there with the same testbed.

Thank you for letting me know.

shyndman avatar Jun 07 '21 21:06 shyndman