我正在制作一个Web应用程序。我有一个WebAPI,我的应用程序通过HTTPS与之连接。 首先是用户登录-WebAPI从WebApplication获取数据后登录用户,并发送BearerToken和RefreshToken。
接下来,我的WebApplication存储令牌。 BearerToken被添加到对WebAPI的每个请求中。 15分钟后,承载到期。现在,应用程序应该使用刷新令牌来获取新的承载令牌。我以非常简单的方式做到了。我所有的请求都通过这种方法:
public async Task<HttpResponseMessage> SendAsyncRequest(string uri, string content, HttpMethod method, bool tryReauthorizeOn401 = true)
{
try
{
HttpRequestMessage rm = new HttpRequestMessage(method, uri);
if (!string.IsNullOrWhiteSpace(content))
rm.Content = new StringContent(content, Encoding.UTF8, ContentType);
HttpResponseMessage response = await httpClient.SendAsync(rm);
if (response.StatusCode == HttpStatusCode.Unauthorized && tryReauthorizeOn401)
{
httpClient.CancelPendingRequests();
bool res = await OnReauthorizeUser();
if (!res)
return response;
return await SendAsyncRequest(uri, content, method, false);
}
return response;
}catch(Exception ex)
{
Debug.Assert(false, ex.Message);
throw;
}
}
应该这样工作:
OnReauthorizeUser
事件SendAsyncRequest
我希望它能工作。但事实并非如此。事实证明,当我使用重新授权数据调用SendAsynRequest
时,会收到TaskCancelletionException。没有任何超时。碰到这个问题时:httpClient.SendAsync(rm);
因此,我的代码“返回”到res == false的OnReauthorizeUser
(上一次调用)之后。
所以,我想也许我会以某种方式扭曲WebApplication http请求生命周期。我确认在一个请求期间(例如,用户单击具有受保护资源的链接),我尝试发送两个请求:
我是对的吗?如何避免此类问题?我该怎么办:
换句话说:
/documents/user/user-id
/tokens/refresh/
/documents/user/user-id
所以我想实现这种情况。 用户单击链接一次,然后查看其文档列表。无需重新登录(我们假设他已登录,承载令牌已自然过期,并且刷新令牌有效)