1
0
Cardidi cdcd1d62ab fix: Adjust api namespace
feat: Add Avalonia client base.
2025-03-27 02:06:48 +08:00

52 lines
2.0 KiB
C#

using System;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using Flawless.Client.Remote;
namespace Flawless.Client;
public class AuthHeaderHandler : DelegatingHandler
{
private string? AuthenticationHeader { get; set; }
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var response = await SendCommandAsync(request, cancellationToken);
var retryCount = 0;
while (response.Headers.TryGetValues("Token-Expired", out var expired) && expired.Any(s => s == "true"))
{
if (retryCount++ > 3)
{
AuthenticationHeader = null;
throw new TimeoutException("Too many retries, login info was cleared");
}
var refreshRequest = new HttpRequestMessage(HttpMethod.Post, "api/auth/refresh");
var refresh = await base.SendAsync(refreshRequest, cancellationToken);
if (!response.IsSuccessStatusCode) throw new ApplicationException("Login is expired and require login!");
await using var st = await refresh.Content.ReadAsStreamAsync(cancellationToken);
var tk = await JsonSerializer.DeserializeAsync<TokenInfo>(st, cancellationToken: cancellationToken)
?? throw new ApplicationException("Not able to refresh token, please login again!");
AuthenticationHeader = tk.Token;
response = await SendCommandAsync(request, cancellationToken);
}
return response;
}
private Task<HttpResponseMessage> SendCommandAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
// Prefill this header
if (AuthenticationHeader != null)
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", AuthenticationHeader);
return base.SendAsync(request, cancellationToken);
}
}