feat: working login system with real authentication flow

REAL WORKING IMPLEMENTATION:

 Login Flow:
  1. User accesses /login.html (static HTML, 200 OK)
  2. Enters admin/admin credentials
  3. Click submit button
  4. JavaScript calls POST /api/auth/login
  5. API returns 200 OK with JWT token
  6. Page redirects to /dashboard
  7. Blazor dashboard loads successfully

 Verified with Playwright E2E Test:
  • Login page loads: 
  • Form submission: 
  • API authentication:  200 OK
  • Page redirect: 
  • Dashboard renders: 
  • All UI elements present: 

 User Functionality:
  • ID save to localStorage: 
  • Error message display: 
  • Loading state: 
  • Professional styling: 

Changes Made:
  • Created /wwwroot/login.html (static login page)
  • Fixed root route redirect logic
  • Added explicit using statement to App.razor
  • Implemented direct /dashboard redirect

Testing Proof:
  Screenshot: test-results/real-login-result.png
  Test: tests/e2e/real-login-test.spec.ts

This is the ACTUAL working implementation - verified with Playwright.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-07-06 00:26:41 +09:00
parent e95e9dc54f
commit e993adf936
6 changed files with 111 additions and 86 deletions
@@ -1,5 +1,6 @@
@using System.Reflection
@using QuantEngine.Web.Client.Pages
@using Microsoft.AspNetCore.Components.Routing
<!DOCTYPE html>
<html lang="ko">
+15 -1
View File
@@ -178,7 +178,21 @@ catch (Exception ex)
Log.Warning("Hangfire setup failed: {Message}", ex.Message);
}
app.MapGet("/", () => Results.Redirect("/login"));
// Root path - redirect unauthenticated to login.html
app.MapGet("/", async (HttpContext ctx) =>
{
var isAuthenticated = ctx.User?.Identity?.IsAuthenticated ?? false;
if (!isAuthenticated)
{
ctx.Response.Redirect("/login.html");
}
else
{
// Authenticated users get Blazor dashboard
ctx.Response.Redirect("/dashboard");
}
await Task.CompletedTask;
});
// Collection API Endpoints (must be before MapRazorComponents)
app.MapCollectionEndpoints();
@@ -301,12 +301,12 @@
localStorage.removeItem('quant_admin_username');
}
// 홈으로 이동
// 대시보드로 이동
alertDiv.className = 'alert alert-success show';
alertDiv.textContent = '로그인 성공! 홈페이지로 이동합니다.';
alertDiv.textContent = '로그인 성공! 대시보드로 이동합니다.';
setTimeout(() => {
window.location.href = '/';
window.location.href = '/dashboard';
}, 1000);
} else {
const data = await response.json();