52 lines
2.0 KiB
C#
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);
|
|
}
|
|
} |