I'm starting out with the newer UWP based application development. While writing an http request client, I noticed that most of my requests needed the Authorization
header present. Hence, I implemented/copied the sample plugin filter provided in the MSDN docs.
Now, I have 2 methods in my base http client class, one which makes use of the static/singleton client created with the above filter in place, and another which creates a new HttpClient
on every call (for first time login).
I am planning to use the first time login method to be used over in case the authorization token expires in my filter. To achieve this, I naively implemented a do-while loop:
// The following snippet is from the IHttpFilter implementation
public IAsyncOperationWithProgress<HttpResponseMessage, HttpProgress> SendRequestAsync(HttpRequestMessage request)
{
return AsyncInfo.Run<HttpResponseMessage, HttpProgress>(async (cancellation, progress) =>
{
int retries = 0;
HttpResponseMessage response;
do
{
string authToken = UserSettings.Instance.AccessToken;
request.Headers.Authorization = HttpCredentialsHeaderValue.Parse($"Bearer {authToken}");
response = await baseFilter.SendRequestAsync(request).AsTask(cancellation, progress);
if (!response.IsSuccessStatusCode && response.StatusCode == HttpStatusCode.Unauthorized)
{
new AuthClient().GenerateAccessToken(AuthGrantType.REFRESH);
}
} while (response.StatusCode == HttpStatusCode.Unauthorized && ++retries < 3);
cancellation.ThrowIfCancellationRequested();
return response;
});
}
where, my AuthClient.GenerateAccessToken
takes care of updating the UserSettings
lazy instance.
This do-while
block is able to update the authToken
value in case the old one has expired, but when it goes back to the loop again, it raises the following exception:
An exception of type 'System.InvalidOperationException' occurred in System.Private.CoreLib.dll but was not handled in user code
A method was called at an unexpected time. (Exception from HRESULT: 0x8000000E)
I understand that my task from before was cached, and since I await
ed it in the first run, the task is over.
How should I implement the logic for relogin in case of expired token? Should there be another filter placed which only deals with the response.StatusCode == Unauthorized
case? What else would be suggested for this pattern?
User contributions licensed under CC BY-SA 3.0