HttpClient.DefaultRequestHeaders.Authorization 为空?

HttpClient.DefaultRequestHeaders.Authorization is null?

我获取令牌并将其添加到注入的 HttpClient 的授权 header:

    public MyAuthenticationService(HttpClient globalHttpClient)
    {
        _globalHttpClient = globalHttpClient;
    }

    public void Login(..)
    {
        ..
        ((AuthStateProvider)_authenticationStateProvider).NotifyUserAuthentication(token);
        AddAccessTokenToHttpClientHeader(token);
    }

    private void AddAccessTokenToHttpClientHeader(string accessToken)
    {
        _globalHttpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", accessToken);
    }

到目前为止一切顺利,我检查并设置了令牌和 header。但随后我的第一个 api 调用了另一项服务:

var test = _httpClient.DefaultRequestHeaders.Authorization; // test is null!
return await ApiUtils.GetList<T>(_httpClient, uri, _logger); // Error: 401

这是一个不同的 HttpClient 还是什么?我是正常注射的。在 Startup.cs 我有这一行:

services.AddHttpClient();

我让它工作了,但它远非理想。我将 _Host.cshtml 中的渲染模式设置为:

render-mode="Server"

然后我手动设置:

string? token = await _localStorageService.GetItemAsync<string>(Constants.LocalStorage.ACCESS_TOKEN_KEY);
if (!HttpClient.DefaultRequestHeaders.Contains("Authorization") || HttpClient.DefaultRequestHeaders.Authorization == null)
                HttpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
return await ApiUtils.StaticConsumeGetList<T>(HttpClient, uri, _logger);

我希望有人有更好的解决方案。

更新:

显然,与 WASM 相比,这在 Blazor 服务器上的工作方式完全不同。 您不能(而且可能不应该)在 OnAfterRenderAsync() 中从 LocalStorage 检索令牌,因此您必须从 HttpContextAccessor.HttpContext 添加和获取身份验证,而不是使用中间件。然而,这会产生一个问题,即新选项卡和关闭浏览器也会终止您的登录会话,但这是 Blazor Server 应用程序的预期方式。登录会话不应保留多天。此方法还会保留您的预渲染模式。