Ошибка провайдера пользовательской аутентификации Blazor - PullRequest
0 голосов
/ 11 апреля 2020

Я создаю приложение пользовательского интерфейса Blazor для взаимодействия с API. В настоящее время я пытаюсь найти собственного провайдера для этой работы и получаю несколько ошибок.

Это клиент AuthenticationStateProvider

public class APIAuthenticationStateProvider : AuthenticationStateProvider
{
    private readonly HttpClient _httpClient;
    private readonly ILocalStorageService _localStorage;
    public APIAuthenticationStateProvider(HttpClient httpClient, ILocalStorageService localStorage)
    {
        _httpClient = httpClient;
        _localStorage = localStorage;
    }
    public override async Task<AuthenticationState> GetAuthenticationStateAsync()
    {
        var token = await _localStorage.GetItemAsync<string>("authToken");

        if (string.IsNullOrWhiteSpace(token))
        {
            return new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity()));
        }

        _httpClient.DefaultRequestHeaders.Authorization =
            new AuthenticationHeaderValue("bearer", token);

        var claims = ParseClaims(token);

        return new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity(claims,"jwt")));
    }
}

Функция My Configure Services в файле Startup.cs выглядит следующим образом

public void ConfigureServices(IServiceCollection services)
{
    services.AddRazorPages();
    services.AddServerSideBlazor();
    services.AddBlazoredLocalStorage();
    services.AddScoped<AuthenticationStateProvider, APIAuthenticationStateProvider>();
    services.AddTransient<IAuthRepository, AuthRepository>();
    services.AddHttpClient();
}

При выполнении я получаю следующее исключение

InvalidOperationException: JavaScript interop calls cannot be issued at this time. This is because the component is being statically rendererd. When prerendering is enabled, JavaScript interop calls can only be performed during the OnAfterRenderAsync lifecycle method.

Microsoft.AspNetCore.Components.Server.Circuits.RemoteJSRuntime.BeginInvokeJS(long asyncHandle, string identifier, string argsJson)
Microsoft.JSInterop.JSRuntime.InvokeAsync<TValue>(string identifier, CancellationToken cancellationToken, object[] args)
Microsoft.JSInterop.JSRuntime.InvokeWithDefaultCancellation<T>(string identifier, object[] args)
System.Threading.Tasks.ValueTask<TResult>.get_Result()
System.Runtime.CompilerServices.ValueTaskAwaiter<TResult>.GetResult()
Blazored.LocalStorage.LocalStorageService.GetItemAsync<T>(string key)
BookStore_UI.Providers.APIAuthenticationStateProvider.GetAuthenticationStateAsync() in APIAuthenticationStateProvider.cs

Я не уверен, что ошибка ясна, и именно в этом и заключается ошибка, или есть какой-то другой основной шаг, который я пропускаю. Я думаю, что это может быть связано с использованием локального хранилища.

Ответы [ 3 ]

1 голос
/ 07 мая 2020

в _Host.cs html, измените режим рендеринга

render-mode = "ServerPrerendered"

на рендер-режим = "Сервер"

1 голос
/ 11 апреля 2020

Этот код: var token = await _localStorage.GetItemAsync<string>("authToken"); выполняется, пока JavaScript еще не доступен. Посмотрите документы о том, как бороться с такими случаями, когда вы пытаетесь получить доступ к локальному хранилищу. Они конкретно показывают, как выполнить такую ​​задачу.

Ваши ConfigureServices должны выглядеть примерно так:

services.AddRazorPages();
services.AddServerSideBlazor();
services.AddBlazoredLocalStorage();
services.AddHttpClient();
services.AddScoped<APIAuthenticationStateProvider>();
services.AddScoped<AuthenticationStateProvider>(provider => 
       provider.GetRequiredService<APIAuthenticationStateProvider>());
services.AddTransient<IAuthRepository, AuthRepository>();

_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue ("bearer", token );

Метод GetAuthenticationStateAsyn c должен иметь единственную цель: вернуть объект состояния аутентификации, поэтому его не следует использовать для настройки объекта HttpClient. Это следует сделать (прочитав токен Jwt из локального хранилища и назначив его заголовку авторизации запроса) из того самого места, где вы собираетесь вызывать метод службы HttpClient.

Надеюсь, это поможет .. .

0 голосов
/ 12 апреля 2020

Ошибка была связана с тем, что код JS запускался до загрузки всех ресурсов ... в двух словах.

Чтобы предотвратить его падение, я обернул функцию GetAuthenticationStateAsyn c () все в попытку ... поймал и не выдал исключение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...