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 应用程序的预期方式。登录会话不应保留多天。此方法还会保留您的预渲染模式。
我获取令牌并将其添加到注入的 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 应用程序的预期方式。登录会话不应保留多天。此方法还会保留您的预渲染模式。