Files
DbFirst/DbFirst.BlazorWebApp/Services/AuthApiClient.cs
OlgunR 1ad267e409 Add authentication support with login/logout UI
- Introduced AuthService, IAuthApiClient, and AuthApiClient for managing authentication state and API calls (login, logout, session restore).
- Added Login.razor and LoginLayout.razor for the login page, including styling and logic.
- MainLayout.razor now checks authentication on load, restores sessions from sessionStorage, and redirects to /login if unauthenticated. Displays username and logout button when logged in.
- Implemented JS interop (authStorage) for persisting authentication info in sessionStorage.
- Registered AuthService, CookieContainer, and API clients in Program.cs to share cookies and support authentication.
- Updated AppSettings and appsettings files to support separate ApiBaseUrl and DataApiBaseUrl.
- Minor CSS improvements for username display in the top bar.
2026-05-12 16:32:46 +02:00

65 lines
2.3 KiB
C#

using System.Net;
namespace DbFirst.BlazorWebApp.Services;
public class AuthApiClient(HttpClient httpClient, AuthService authService, CookieContainer cookieContainer) : IAuthApiClient
{
private const string LoginEndpoint = "api/Auth/db-first/login";
private const string LogoutEndpoint = "api/Auth/logout";
private const string CheckEndpoint = "api/Auth/check";
public async Task<bool> LoginAsync(string username, string password, CancellationToken ct = default)
{
var content = new MultipartFormDataContent();
content.Add(new StringContent(username), "Username");
content.Add(new StringContent(password), "Password");
content.Add(new StringContent(string.Empty), "UserId");
var response = await httpClient.PostAsync(LoginEndpoint, content, ct);
if (!response.IsSuccessStatusCode)
return false;
var rawCookie = ExtractCookies();
authService.SetAuthenticated(username, rawCookie);
return true;
}
public async Task LogoutAsync(CancellationToken ct = default)
{
await httpClient.PostAsync(LogoutEndpoint, null, ct);
authService.SetUnauthenticated();
}
public async Task<bool> RestoreAsync(string username, string rawCookieHeader, CancellationToken ct = default)
{
RestoreCookies(rawCookieHeader);
var response = await httpClient.GetAsync(CheckEndpoint, ct);
if (response.IsSuccessStatusCode)
{
authService.SetAuthenticated(username, rawCookieHeader);
return true;
}
authService.SetUnauthenticated();
return false;
}
private string ExtractCookies()
{
if (httpClient.BaseAddress is null) return string.Empty;
var cookies = cookieContainer.GetCookies(httpClient.BaseAddress);
return string.Join("; ", cookies.Cast<Cookie>().Select(c => $"{c.Name}={c.Value}"));
}
private void RestoreCookies(string rawCookieHeader)
{
if (httpClient.BaseAddress is null) return;
foreach (var part in rawCookieHeader.Split(';', StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries))
{
var eqIdx = part.IndexOf('=');
if (eqIdx > 0)
cookieContainer.Add(httpClient.BaseAddress, new Cookie(part[..eqIdx].Trim(), part[(eqIdx + 1)..].Trim()));
}
}
}