Refreshing an access token returns new Access Token and new Refresh Token: /oauth/token?grant_type=refresh_token&refresh_token={Refresh Token}
New tokens are valid JWT tokens and can be decoded.
Using a newly refreshed Access Token on any endpoint throws 124:Invalid. This can be repeated over and over - i.e. refreshing a token with a new Refresh Token returns new tokens, and new Access Token throws 124:Invalid.
The only way to get a working valid Access Token is to send a user through initial OAUTH flow: /oauth/authorize?response_type=code&client_id={Client ID}&redirect_uri={Redirect Uri}
I’m not sure if this is related to:
app is not yet live, but we got approval for external testing and have a publishable URL
we’re using production credentials (which seem to work perfectly for initial AT)
we’re refreshing Access Token before it expires - waited for AT to expire, new AT is invalid.
I switched to dev credentials, thinking that maybe it had to do with production restrictions since we’re not live yet, but same issue occurred - can refresh endlessly, but requests fail with invalid AT. That meant it was definitely something on our end.
I used CURL to refresh, then saved to DB so the code would pick it up - that worked - all requests were going through just fine.
That meant there was something in how token data was received/processed/stored on token refresh request.
This is being tested on node.js and we use built-in https module for requests. The code is dumb/simple:
If you can see it - the problem is body.join() - it uses a “,” by default, and sticks it between decoded chunks. So a response string “…NkLTBkYjUtNDE5Z…” turns into “…NkLTBkLTBk,YjUtNDE5Z…”.
While we could still decode the token with a “,” in payload since base64 doesn’t care about commas, obviously when we tried to request with the token, the payload+signature would not match on your end and you would reject it.
Simple switch to the following makes it all work:
response.on('end', () => {
body = Buffer.concat(body).toString();
// or body.join("");
}
And the reason the first access token worked is because OAUTH flow is handled by different code which processed the response correctly without adding “commas”…