0

对于我的应用程序中的每个 API 调用,我想检查用户是否有过期的 JWT,如果是,我想使用刷新令牌获取一个新的,然后继续对 API 的原始请求。这应该全部在后台工作,APP用户不会遇到任何中断或需要再次登录。

我像这样创建我的 HttpClient:

static DelegatingHandler handler = new AuthenticationHandler();

static HttpClient httpClient = new HttpClient(handler)
{
    BaseAddress = new Uri("https://10.0.2.2:5001/api/v1")

};

AuthenticationHandler 是一个自定义的 DelegatingHandler,它有一个覆盖SendAsync方法。在该方法中,我检查请求是否具有状态Unauthorised

 if (response.StatusCode == System.Net.HttpStatusCode.Unauthorized)

如果是这样,我需要使用当前拥有的 JWT 和 Refresh 令牌向我的 API 发送另一个请求以生成新的令牌对......因为这是另一个 API 调用中间的 API 调用(因为这一切都发生在内部自定义 DelegatingHandler 是构造我的主 HttpClient 的参数) - 是否需要使用我需要创建的第二个 HttpClient 来刷新令牌以进行刷新令牌调用?

我看不出如何为此使用相同的 HttpClient,这通常是如何完成的?


编辑:

我看不到如何从 AuthenticationHandler 内部使用相同的 HttpClient 进行 refreshToken 调用,因为处理程序用于构造 HttpClient。感觉像是循环引用。我只是不知道其他人如何在他们的代码中做到这一点......我目前通过使用第二个 HttpClient 来实现它,我只用于那个refreshToken调用,它可以工作,但我觉得有一种更清洁的方法来实现这个?

顺便说一句,我(尚未重构) AuthenticationHandler 中的 SendAsync 方法目前看起来像这样:

protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
    try
    {
        HttpResponseMessage response = new HttpResponseMessage();

        request = CheckForAuthToken(request);

        response = await base.SendAsync(request, cancellationToken).ConfigureAwait(false);

        if (response.StatusCode == System.Net.HttpStatusCode.Unauthorized)
        {
            for (int i = 1; i == _maxRefreshAttempts; i++)
            {

                // Here I make a call to the API to refresh and return a new JWT, The authApiService uses a different HttpClient

                RefreshTokenRequestModel refreshTokenRequestModel = new RefreshTokenRequestModel
                {
                    Token = await SecureStorage.GetAsync("jwtToken"),
                    RefreshToken = await SecureStorage.GetAsync("refreshToken")
                };

                var apiResponse = await authApiService.RefreshToken(refreshTokenRequestModel);


                if (apiResponse.IsSuccessStatusCode)
                {
                    await SecureStorage.SetAsync("jwtToken", apiResponse.Content.Token);
                    await SecureStorage.SetAsync("refreshToken", apiResponse.Content.RefreshToken);

                    request = CheckForAuthToken(request);

                    response = await base.SendAsync(request, cancellationToken).ConfigureAwait(false);
                }
            }
        }

        return response;
    }
    catch (Exception e)
    {

        throw e;
    }
    
}
4

0 回答 0