@page "/admin/login" @layout TaxBaik.Web.Components.Admin.Layout.BlankLayout @attribute [AllowAnonymous] @rendermode @(new InteractiveServerRenderMode(prerender: true)) @inject IApiClient ApiClient @inject ILocalStorageService LocalStorageService @inject IJSRuntime Js 로그인 관리자 로그인
@code { private LoginModel model = new(); private const string RememberedUsernameKey = "admin-remembered-username"; protected override async Task OnInitializedAsync() { try { var remembered = await LocalStorageService.GetItemAsStringAsync(RememberedUsernameKey); if (!string.IsNullOrEmpty(remembered)) { model.Username = remembered; } } catch { // LocalStorage may be unavailable during prerender. } } protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender) await Js.InvokeVoidAsync("taxbaikAdminSession.syncRouteClass"); } private async Task HandleLogin() { var request = new { model.Username, model.Password }; var response = await ApiClient.PostAsync("auth/login", request); if (response?.AccessToken == null || response?.RefreshToken == null) { return; } if (model.RememberMe) { await LocalStorageService.SetItemAsStringAsync(RememberedUsernameKey, model.Username); } else { await LocalStorageService.RemoveItemAsync(RememberedUsernameKey); } await Js.InvokeVoidAsync("localStorage.setItem", "accessToken", response.AccessToken); await Js.InvokeVoidAsync("localStorage.setItem", "refreshToken", response.RefreshToken); await Js.InvokeVoidAsync("localStorage.setItem", "tokenExpiry", DateTimeOffset.UtcNow.AddSeconds(response.ExpiresIn).ToUnixTimeMilliseconds().ToString()); await Js.InvokeVoidAsync("window.location.assign", "/taxbaik/admin/dashboard"); } private class LoginModel { public string Username { get; set; } = ""; public string Password { get; set; } = ""; public bool RememberMe { get; set; } } private class LoginResponse { public string AccessToken { get; set; } = ""; public string RefreshToken { get; set; } = ""; public int ExpiresIn { get; set; } } }