Добавьте файлы проекта.

This commit is contained in:
FrigaT
2026-04-13 14:16:44 +03:00
parent b2b5a3945a
commit 37c997dbe0
120 changed files with 5364 additions and 0 deletions

View File

@@ -0,0 +1,99 @@
using System.Net.Http.Headers;
using System.Security.Claims;
namespace PlaylistShared.PWA.Services;
public class AuthStateProvider : AuthenticationStateProvider, IDisposable
{
private readonly TokenStorage _tokenStorage;
private readonly ApiClient _apiClient;
private readonly HttpClient _http;
private Timer? _refreshTimer;
private ClaimsPrincipal _currentUser = new(new ClaimsIdentity());
public AuthStateProvider(TokenStorage tokenStorage, ApiClient apiClient, HttpClient http)
{
_tokenStorage = tokenStorage;
_apiClient = apiClient;
_http = http;
}
public override async Task<AuthenticationState> GetAuthenticationStateAsync()
{
var (token, refreshToken) = await _tokenStorage.GetTokensAsync();
if (string.IsNullOrEmpty(token))
return new AuthenticationState(_currentUser);
var principal = ParseToken(token);
if (principal == null)
return new AuthenticationState(_currentUser);
_currentUser = principal;
_http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
ScheduleTokenRefresh(token, refreshToken);
return new AuthenticationState(principal);
}
public async Task MarkUserAsAuthenticated(string token, string refreshToken)
{
await _tokenStorage.SetTokensAsync(token, refreshToken);
var principal = ParseToken(token);
_currentUser = principal ?? new ClaimsPrincipal(new ClaimsIdentity());
_http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
NotifyAuthenticationStateChanged(GetAuthenticationStateAsync());
}
public async Task MarkUserAsLoggedOut()
{
await _tokenStorage.ClearTokensAsync();
_currentUser = new ClaimsPrincipal(new ClaimsIdentity());
_http.DefaultRequestHeaders.Authorization = null;
NotifyAuthenticationStateChanged(GetAuthenticationStateAsync());
}
private ClaimsPrincipal? ParseToken(string token)
{
try
{
var handler = new JwtSecurityTokenHandler();
var jwt = handler.ReadJwtToken(token);
var identity = new ClaimsIdentity(jwt.Claims, "jwt");
return new ClaimsPrincipal(identity);
}
catch
{
return null;
}
}
private void ScheduleTokenRefresh(string token, string? refreshToken)
{
var handler = new JwtSecurityTokenHandler();
var jwt = handler.ReadJwtToken(token);
var expiresAt = jwt.ValidTo;
var timeToExpiry = expiresAt - DateTime.UtcNow;
var refreshTime = timeToExpiry - TimeSpan.FromMinutes(5);
if (refreshTime > TimeSpan.Zero && !string.IsNullOrEmpty(refreshToken))
{
_refreshTimer?.Dispose();
_refreshTimer = new Timer(async _ =>
{
try
{
var newToken = await _apiClient.RefreshTokenAsync(refreshToken);
if (newToken != null)
await MarkUserAsAuthenticated(newToken.Token, newToken.RefreshToken);
else
await MarkUserAsLoggedOut();
}
catch
{
await MarkUserAsLoggedOut();
}
}, null, (int)refreshTime.TotalMilliseconds, Timeout.Infinite);
}
}
public void Dispose() => _refreshTimer?.Dispose();
}