繁体   English   中英

在 blazor 中使用带有身份验证的 WebAPI

[英]Consuming WebAPI in blazor with authentication

我在创建 ASP.NET WebAPI 项目时使用 VS 2019 提供的天气预报数据的基本模板,并添加了一些非常基本的用户登录身份验证和对 JWT 令牌的支持,一切正常。

我正在尝试创建一个 blazor 客户端项目来使用 API 并在页面上显示数据。 AFAIK Blazor 不支持 localstorage 所以我使用 Blazored LocalStorage package 来给我这个能力。 我的问题源于在服务器端 blazor ( https://github.com/aspnet/AspNetCore/issues/13396 )中无法通过 OnInitializedAsync() 使用 JS 的事实,因此我不确定如何使用这些 web api 调用。 因为这将产生一个 null 参考异常

protected override async Task OnInitializedAsync()
{
    var client = HttpFactory.CreateClient();
    var token = await LocalStorage.GetItemAsync<string>("authToken");
    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
    var response = await client.GetAsync("url/WeatherForecast");
    var str = await response.Content.ReadAsStringAsync();
    Items = JsonConvert.DeserializeObject<IEnumerable<WeatherForecast>>(str);
}

一个建议是使用 OnAfterRenderAsync() 方法来调用它们,因为那时 JS 已经准备好了。 哪个半工作但显然 UI 不匹配,因为它需要刷新 - 但是要手动刷新它似乎我必须调用 StateHasChanged(); 这反过来又再次调用 OnAfterRender 方法,结果我不得不进行检查,但这最终感觉非常糟糕。

private bool hasRendered;
protected override async Task OnAfterRenderAsync(bool _)
{
    if (!hasRendered) return;
    var client = HttpFactory.CreateClient();
    var token = await LocalStorage.GetItemAsync<string>("authToken");
    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
    var response = await client.GetAsync("https://url/WeatherForecast");
    var str = await response.Content.ReadAsStringAsync();
    Items = JsonConvert.DeserializeObject<IEnumerable<WeatherForecast>>(str);

    StateHasChanged();

    hasRendered = true;
}

使用具有身份验证功能的 API 并在客户端正确显示数据的正确方法是什么?

附带问题 HttpClient 似乎不能在服务器端注入,建议使用 HttpClientFactory - 在每个请求上创建一个客户端或创建一个 singleton 并在整个客户端项目中重复使用是个好主意吗?

第一季度

一个建议是使用 OnAfterRenderAsync() 方法来调用它们,因为那时 JS 已经准备好了。 哪个半工作但显然 UI 不匹配,因为它需要刷新 - 但是要手动刷新它似乎我必须调用 StateHasChanged(); 这反过来又再次调用 OnAfterRender 方法,结果我不得不进行检查,但这最终感觉非常糟糕。

所有人都有同样的问题,因为在Lifecycle methods中,记录了带有firstRender parm 的新OnAfterRenderAsync

protected override async Task OnAfterRenderAsync(bool firstRender)
{
    if (firstRender)
    {
        await ... /// your auth code here.
    }
}

第二季度

附带问题 HttpClient 似乎不能在服务器端注入,建议使用 HttpClientFactory - 在每个请求上创建一个客户端或创建一个 singleton 并在整个客户端项目中重复使用是个好主意吗?

Simplifying: I suggest to you to create two external libraries for your backend calls: one using http requests (for blazor wasm hosted model) and the other one just calling c# backend functions (for blazor server). 两者都具有用于后端调用的通用接口。 使用DI 为每个托管的 model 设置正确的库

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM