-
Notifications
You must be signed in to change notification settings - Fork 142
Description
Hi,
When I make an API request with a token that is expired I receive the following error:
FitbitTokenException: In interceptor OAuth2AutoRefreshInterceptor inside method InterceptResponse we received an unexpected stale token response - during the retry for a call whose token we just refreshed 401
I traced this to the following method in OAuth2AutoRefreshInterceptor.cs:
public async Task<HttpResponseMessage> InterceptResponse(Task<HttpResponseMessage> response, CancellationToken cancellationToken, FitbitClient Client)
{
if (response.Result.StatusCode == System.Net.HttpStatusCode.Unauthorized)//Unauthorized, then there is a chance token is stale
{
var responseBody = await response.Result.Content.ReadAsStringAsync();
if (IsTokenStale(responseBody))
{
Debug.WriteLine("Stale token detected. Invoking registered tokenManager.RefreskToken to refresh it");
await Client.RefreshOAuth2TokenAsync();
//Only retry the first time.
if (!response.Result.RequestMessage.Headers.Contains(CUSTOM_HEADER))
{
var clonedRequest = await response.Result.RequestMessage.CloneAsync();
clonedRequest.Headers.Add(CUSTOM_HEADER, CUSTOM_HEADER);
return await Client.HttpClient.SendAsync(clonedRequest, cancellationToken);
}
else if (response.Result.RequestMessage.Headers.Contains(CUSTOM_HEADER))
{
throw new FitbitTokenException(response.Result, message: $"In interceptor {nameof(OAuth2AutoRefreshInterceptor)} inside method {nameof(InterceptResponse)} we received an unexpected stale token response - during the retry for a call whose token we just refreshed {(int)response.Result.StatusCode}");
}
}
}
//let the pipeline continue
return null;
}
When debugging I verified that Client.RefreshOAuth2TokenAsync(); does actually refresh the AccessToken.
However clonedRequest uses the old AccessToken in the Authorization header and not the newly refreshed AccessToken, therefore the request fails again and this triggers the 'unexpected stale token response'-FitbitTokenException as the request now contains the custom header.
Adding clonedRequest.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", Client.AccessToken.Token);
here:
if (!response.Result.RequestMessage.Headers.Contains(CUSTOM_HEADER))
{
var clonedRequest = await response.Result.RequestMessage.CloneAsync();
clonedRequest.Headers.Add(CUSTOM_HEADER, CUSTOM_HEADER);
clonedRequest.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", Client.AccessToken.Token);
return await Client.HttpClient.SendAsync(clonedRequest, cancellationToken);
}
fixes this.