用刷新令牌刷新Bearer令牌-请求和HttpClient问题

时间:2020-06-29 08:44:42

标签: c# asp.net-web-api httprequest dotnet-httpclient

我正在制作一个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;
    }            
}

应该这样工作:

  • 我发送了一个请求
  • 如果我收到401响应并且tryReauthorizeOn401 == true,我会调用OnReauthorizeUser事件
  • 在此事件处理程序中(此处未显示),我最终再次使用重新授权数据再次调用SendAsyncRequest

我希望它能工作。但事实并非如此。事实证明,当我使用重新授权数据调用SendAsynRequest时,会收到TaskCancelletionException。没有任何超时。碰到这个问题时:httpClient.SendAsync(rm);因此,我的代码“返回”到res == false的OnReauthorizeUser(上一次调用)之后。

所以,我想也许我会以某种方式扭曲WebApplication http请求生命周期。我确认在一个请求期间(例如,用户单击具有受保护资源的链接),我尝试发送两个请求:

  • 获取受保护的资源
  • 在主请求结束之前重新授权

我是对的吗?如何避免此类问题?我该怎么办:

  • 当我收到401响应时,系统应自动刷新令牌并再次调用请求吗?

换句话说:

  • 用户单击“显示我的文档”链接
  • 应用程序将请求发送到WebAPI:/documents/user/user-id
  • 我收到来自WebAPI的响应,出现401错误
  • 然后,应用程序通过向WebAPI发送请求来重新授权用户:/tokens/refresh/
  • 我从WebAPI得到了带有新令牌的响应(我们假设我会得到这个)
  • 应用程序然后再次从第二步发送请求:/documents/user/user-id

所以我想实现这种情况。 用户单击链接一次,然后查看其文档列表。无需重新登录(我们假设他已登录,承载令牌已自然过期,并且刷新令牌有效)

0 个答案:

没有答案