3e7120c041
WBS-9.3 - NULL Policy CI Gate / NULL Policy Validation (push) Failing after 5s
Quant Engine CI/CD Pipeline / validate-core (push) Failing after 10s
Quant Engine CI/CD Pipeline / validate-ui-and-storage (push) Has been skipped
Deploy to Production / Build & Deploy to Production (push) Failing after 1m49s
125 lines
4.6 KiB
Plaintext
125 lines
4.6 KiB
Plaintext
@page "/login"
|
|
@attribute [AllowAnonymous]
|
|
@layout AuthLayout
|
|
@inject AuthenticationStateProvider AuthStateProvider
|
|
@inject NavigationManager NavigationManager
|
|
@inject HttpClient Http
|
|
|
|
<PageTitle>로그인 - QuantEngine</PageTitle>
|
|
|
|
<MudContainer MaxWidth="MaxWidth.False" Class="login-shell">
|
|
<MudPaper Class="login-card pa-8" Elevation="10">
|
|
<MudStack AlignItems="AlignItems.Center" Spacing="2" Class="mb-6">
|
|
<MudAvatar Size="Size.Large" Color="Color.Primary">Q</MudAvatar>
|
|
<MudText Typo="Typo.h4">QuantEngine</MudText>
|
|
<MudText Typo="Typo.body2" Align="Align.Center">은퇴자산포트폴리오 투자 관리 시스템</MudText>
|
|
</MudStack>
|
|
|
|
<MudStack Spacing="2">
|
|
<MudTextField Label="관리자 아이디" @bind-Value="Username" Variant="Variant.Outlined" Immediate="true" AutoFocus="true" />
|
|
<MudTextField Label="비밀번호" @bind-Value="Password" Variant="Variant.Outlined" InputType="InputType.Password" Immediate="true" />
|
|
<MudCheckBox T="bool" @bind-Checked="RememberUsername" Color="Color.Primary" Label="아이디 저장" />
|
|
|
|
@if (!string.IsNullOrEmpty(ErrorMessage))
|
|
{
|
|
<MudAlert Severity="Severity.Error">@ErrorMessage</MudAlert>
|
|
}
|
|
|
|
<MudButton Variant="Variant.Filled" Color="Color.Primary" FullWidth="true" Disabled="@IsSubmitting" OnClick="HandleLoginAsync">
|
|
@(IsSubmitting ? "인증 중..." : "로그인")
|
|
</MudButton>
|
|
</MudStack>
|
|
</MudPaper>
|
|
</MudContainer>
|
|
|
|
<style>
|
|
.login-shell {
|
|
min-height: 100vh;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
background:
|
|
radial-gradient(circle at top left, rgba(0, 242, 254, 0.08), transparent 30%),
|
|
radial-gradient(circle at bottom right, rgba(79, 172, 254, 0.1), transparent 35%),
|
|
linear-gradient(135deg, #090a15 0%, #12142d 100%);
|
|
}
|
|
|
|
.login-card {
|
|
width: min(480px, calc(100vw - 32px));
|
|
border-radius: 20px;
|
|
background: rgba(255, 255, 255, 0.04);
|
|
backdrop-filter: blur(24px);
|
|
color: white;
|
|
}
|
|
</style>
|
|
|
|
@code {
|
|
private string Username { get; set; } = string.Empty;
|
|
private string Password { get; set; } = string.Empty;
|
|
private string ErrorMessage { get; set; } = string.Empty;
|
|
private bool IsSubmitting { get; set; } = false;
|
|
private bool RememberUsername { get; set; } = true;
|
|
|
|
protected override async Task OnInitializedAsync()
|
|
{
|
|
var customProvider = (CustomAuthenticationStateProvider)AuthStateProvider;
|
|
var remembered = await customProvider.GetRememberedUsernameAsync();
|
|
if (!string.IsNullOrWhiteSpace(remembered))
|
|
{
|
|
Username = remembered;
|
|
RememberUsername = true;
|
|
}
|
|
}
|
|
|
|
private sealed class LoginResponse
|
|
{
|
|
public bool Success { get; set; }
|
|
public string? Username { get; set; }
|
|
public string? Role { get; set; }
|
|
public string? AccessToken { get; set; }
|
|
public string? ExpiresAt { get; set; }
|
|
}
|
|
|
|
private async Task HandleLoginAsync()
|
|
{
|
|
ErrorMessage = string.Empty;
|
|
if (string.IsNullOrWhiteSpace(Username) || string.IsNullOrWhiteSpace(Password))
|
|
{
|
|
ErrorMessage = "아이디와 비밀번호를 모두 입력해 주세요.";
|
|
return;
|
|
}
|
|
|
|
IsSubmitting = true;
|
|
|
|
try
|
|
{
|
|
var response = await Http.PostAsJsonAsync("api/auth/login", new { Username, Password });
|
|
if (response.IsSuccessStatusCode)
|
|
{
|
|
var auth = await response.Content.ReadFromJsonAsync<LoginResponse>();
|
|
if (auth is null || string.IsNullOrWhiteSpace(auth.AccessToken))
|
|
{
|
|
ErrorMessage = "로그인 응답이 유효하지 않습니다.";
|
|
return;
|
|
}
|
|
|
|
var customProvider = (CustomAuthenticationStateProvider)AuthStateProvider;
|
|
await customProvider.MarkUserAsAuthenticatedAsync(auth.Username ?? Username, auth.AccessToken, auth.Role ?? "Admin", RememberUsername);
|
|
NavigationManager.NavigateTo("/dashboard");
|
|
}
|
|
else
|
|
{
|
|
ErrorMessage = "아이디 또는 비밀번호가 올바르지 않습니다.";
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
ErrorMessage = $"로그인 중 오류가 발생했습니다: {ex.Message}";
|
|
}
|
|
finally
|
|
{
|
|
IsSubmitting = false;
|
|
}
|
|
}
|
|
}
|