Чего мне не хватает для аутентификации моего пользователя?Разве Microsoft.AspNetCore.Authentication.JwtBearer не обрабатывает клиентскую часть (хранит токен)?
JwtBearer
выполняется на стороне сервера, он только проверяет заголовок авторизации запроса, а именно Authorization: Bearer your_access_token
, и не будет заботиться о том, как работают ваши коды WebAssembly.Так что вам нужно отправить запрос с jwt accessToken.Так как в руководстве предлагается использовать localStorage
, давайте сохраним accessToken
с localStorage
.
Поскольку WebAssembly
пока не имеет доступа к BOM
, нам нужны некоторые коды javascript, используемые как клей.Чтобы сделать это, добавьте helper.js
под JwtAuthentication.Client/wwwroot/js/
:
var wasmHelper = {};
wasmHelper.ACCESS_TOKEN_KEY ="__access_token__";
wasmHelper.saveAccessToken = function (tokenStr) {
localStorage.setItem(wasmHelper.ACCESS_TOKEN_KEY,tokenStr);
};
wasmHelper.getAccessToken = function () {
return localStorage.getItem(wasmHelper.ACCESS_TOKEN_KEY);
};
и сделайте ссылку на скрипт в вашем JwtAuthentication.Client/wwwroot/index.html
<body>
<app>Loading...</app>
<script src="js/helper.js"></script>
<script src="_framework/blazor.webassembly.js"></script>
</body>
Теперь давайте упаковываем коды JavaScript вC #.Создайте новый файл Client/Services/TokenService.cs
:
public class TokenService
{
public Task SaveAccessToken(string accessToken) {
return JSRuntime.Current.InvokeAsync<object>("wasmHelper.saveAccessToken",accessToken);
}
public Task<string> GetAccessToken() {
return JSRuntime.Current.InvokeAsync<string>("wasmHelper.getAccessToken");
}
}
Зарегистрируйте эту услугу:
// file: Startup.cs
services.AddSingleton<TokenService>(myTokenService);
И теперь мы можем вставить TokenService
в Login.cshtml
и использовать его для сохранения токена:
@using JwtAuthentication.Client.Services
// ...
@page "/login"
// ...
@inject TokenService tokenService
// ...
@functions {
public string Email { get; set; } = "";
public string Password { get; set; } = "";
public string Token { get; set; } = "";
/// <summary>
/// response from server
/// </summary>
private class TokenResponse{
public string Token;
}
private async Task SubmitForm()
{
var vm = new TokenViewModel
{
Email = Email,
Password = Password
};
var response = await Http.PostJsonAsync<TokenResponse>("http://localhost:57778/api/Token", vm);
await tokenService.SaveAccessToken(response.Token);
}
}
Допустим, вы хотите отправить данные в пределах FetchData.cshtml
@functions {
WeatherForecast[] forecasts;
protected override async Task OnInitAsync()
{
var token = await tokenService.GetAccessToken();
Http.DefaultRequestHeaders.Add("Authorization",String.Format("Bearer {0} ",token));
forecasts = await Http.GetJsonAsync<WeatherForecast[]>("api/SampleData/WeatherForecasts");
}
}
, и результат будет: