Добрый день, у меня в проекте JWT аутентификация. Я хочу правильно научиться работать с обновлением токена. Не могу корректно создать архитектуру. Суть в том, что бы обновлять JWT токен перед отправкой HTTP запроса к API.
У меня есть код на получение списка пользователей в UserService
public class UserService : IUserRepository
{
public UserService() {
}
public async Task<List<ExchangesViewModel>> GetExchanges()
{
return await new HttpClient().GetFromJsonAsync<List<ExchangesViewModel>>("https://ip:5007/api/Crypto/GetExchanges");
}
public async Task<AuthenticatedResponse> Login(SU_001LoginViewModel sU_001LoginViewModel)
{
var options = new RestClientOptions("https://ip:5007")
{
MaxTimeout = -1,
};
var client = new RestClient(options);
var request = new RestRequest("/api/User/Login", Method.Post);
request.AddParameter("application/json", JsonSerializer.Serialize(sU_001LoginViewModel), ParameterType.RequestBody);
var r = client.ExecuteAsync(request).Result.Content;
var userd = JsonSerializer.Deserialize<AuthenticatedResponse>(r);
return userd;
}
public async Task<AuthenticatedResponse> Refresh(AuthenticatedResponse sU_001LoginViewModel)
{
var options = new RestClientOptions("https://ip:5007")
{
MaxTimeout = -1,
};
var client = new RestClient(options);
var request = new RestRequest("/api/User/Refresh", Method.Post);
request.AddParameter("application/json", JsonSerializer.Serialize(sU_001LoginViewModel), ParameterType.RequestBody);
var r = client.ExecuteAsync(request).Result.Content;
var userd = JsonSerializer.Deserialize<AuthenticatedResponse>(r);
return userd;
}
public async Task<List<SU_001ListViewModel>> GetUsers(string token)
{
try
{
var options = new RestClientOptions("https://ip:5007")
{
MaxTimeout = -1,
};
var client = new RestClient(options);
var request = new RestRequest("/api/User/GetUsers", Method.Get);
//request.AddParameter("application/json", token, ParameterType.RequestBody);
request.AddParameter("token", token);
var r = client.ExecuteAsync(request).Result.Content;
var userd = JsonSerializer.Deserialize<List<SU_001ListViewModel>>(r);
return userd;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
return new List<SU_001ListViewModel> { };
}
}
}
В представлении есть следующий код:
var AccessToken = await ProtectedLocalStore.GetAsync<string>("AccessToken");
var RefreshToken = await ProtectedLocalStore.GetAsync<string>("RefreshToken");
var result = await ProtectedLocalStore.GetAsync<string>("AccessToken");
if (result.Value != null)
{
AuthenticatedResponse aresp = new AuthenticatedResponse();
aresp.AccessToken = AccessToken.Value;
aresp.RefreshToken = RefreshToken.Value;
Console.WriteLine("old token");
Console.WriteLine(aresp.AccessToken);
AuthenticatedResponse a = await UserRepository.Refresh(aresp);
Console.WriteLine("New token");
Console.WriteLine(a.AccessToken);
await ProtectedLocalStore.SetAsync("RefreshToken", a.RefreshToken!);
await ProtectedLocalStore.SetAsync("AccessToken", a.AccessToken!);
if (a.AccessToken != null)
{
exchanges = await UserRepository.GetUsers(a.AccessToken!.ToString());
}
Console.WriteLine(exchanges.First().FirstName);
StateHasChanged();
}
Все работает, код
await UserRepository.GetUsers(a.AccessToken!.ToString());
у меня выполняется только после того как я в localstorage обновлю accesstoken и его передам в запрос. Но я думаю что это не лучший вариант мне на каждом представлении писать такой код. Есть вариант как-нибудь по-нормальному обновить токен в localstorage и уже обновленный токен отправлять в запрос?
Я пробовал реализовать способ обновления токена при входе на сайт, но из-за того что запросы асинхронные иногда выпадает так что запрос списка пользователей срабатывает быстрее чем пока придет ответ с данными по новому токену.