서버 게시글
This commit is contained in:
106
GameServer/Controllers/Portfolio/PortfolioAuthController.cs
Normal file
106
GameServer/Controllers/Portfolio/PortfolioAuthController.cs
Normal file
@@ -0,0 +1,106 @@
|
||||
using System.Security.Claims;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.RateLimiting;
|
||||
using GameServer.Models;
|
||||
using GameServer.Models.Portfolio;
|
||||
using GameServer.Services;
|
||||
|
||||
namespace GameServer.Controllers.Portfolio
|
||||
{
|
||||
/// <summary>
|
||||
/// 포트폴리오 관리자 로그인 / 로그아웃 / 세션 확인 API.
|
||||
/// 게임 API(/myGame/*) 와는 완전히 분리된 /api/portfolio/auth 경로를 사용한다.
|
||||
/// </summary>
|
||||
[ApiController]
|
||||
[Route("api/portfolio/auth")]
|
||||
public class PortfolioAuthController : ControllerBase
|
||||
{
|
||||
private readonly PortfolioAdminAuth _auth;
|
||||
|
||||
public PortfolioAuthController(PortfolioAdminAuth auth)
|
||||
{
|
||||
_auth = auth;
|
||||
}
|
||||
|
||||
/// <summary>비밀번호로 로그인하고 관리자 쿠키를 발급한다.</summary>
|
||||
[HttpPost("login")]
|
||||
[EnableRateLimiting("portfolio-login")]
|
||||
public async Task<IActionResult> Login([FromBody] LoginRequestDto request)
|
||||
{
|
||||
// 비밀번호가 아직 설정되지 않았다면 503 으로 안내한다.
|
||||
if (!_auth.IsConfigured)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status503ServiceUnavailable, new ApiResponse<AuthStateDto>
|
||||
{
|
||||
Data = new AuthStateDto { Authenticated = false },
|
||||
Message = "관리자 비밀번호가 설정되지 않았습니다. appsettings.json의 Portfolio:AdminPassword 를 변경해 주세요."
|
||||
});
|
||||
}
|
||||
|
||||
if (!_auth.Verify(request?.Password))
|
||||
{
|
||||
return StatusCode(StatusCodes.Status401Unauthorized, new ApiResponse<AuthStateDto>
|
||||
{
|
||||
Data = new AuthStateDto { Authenticated = false },
|
||||
Message = "비밀번호가 올바르지 않습니다."
|
||||
});
|
||||
}
|
||||
|
||||
// 관리자 신원 발급 (7일 유지)
|
||||
var claims = new List<Claim>
|
||||
{
|
||||
new Claim(ClaimTypes.Name, "admin"),
|
||||
new Claim(ClaimTypes.Role, "admin")
|
||||
};
|
||||
|
||||
var identity = new ClaimsIdentity(claims, PortfolioAdminAuth.CookieScheme);
|
||||
var principal = new ClaimsPrincipal(identity);
|
||||
|
||||
var props = new AuthenticationProperties
|
||||
{
|
||||
IsPersistent = true,
|
||||
ExpiresUtc = DateTimeOffset.UtcNow.AddDays(7)
|
||||
};
|
||||
|
||||
await HttpContext.SignInAsync(PortfolioAdminAuth.CookieScheme, principal, props);
|
||||
|
||||
return Ok(new ApiResponse<AuthStateDto>
|
||||
{
|
||||
Data = new AuthStateDto { Authenticated = true },
|
||||
Message = "로그인되었습니다."
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>관리자 쿠키를 만료시킨다. 언제 호출해도 200.</summary>
|
||||
[HttpPost("logout")]
|
||||
public async Task<IActionResult> Logout()
|
||||
{
|
||||
await HttpContext.SignOutAsync(PortfolioAdminAuth.CookieScheme);
|
||||
|
||||
return Ok(new ApiResponse<AuthStateDto>
|
||||
{
|
||||
Data = new AuthStateDto { Authenticated = false },
|
||||
Message = "로그아웃되었습니다."
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 현재 로그인 상태를 알려준다. 절대 401 을 돌려주지 않는다.
|
||||
/// Message 에는 비밀번호 설정 여부("configured" / "not-configured")를 담아
|
||||
/// 관리자 화면이 안내 문구를 띄울 수 있게 한다.
|
||||
/// </summary>
|
||||
[HttpGet("me")]
|
||||
public async Task<IActionResult> Me()
|
||||
{
|
||||
var result = await HttpContext.AuthenticateAsync(PortfolioAdminAuth.CookieScheme);
|
||||
bool authenticated = result.Succeeded && result.Principal?.Identity?.IsAuthenticated == true;
|
||||
|
||||
return Ok(new ApiResponse<AuthStateDto>
|
||||
{
|
||||
Data = new AuthStateDto { Authenticated = authenticated },
|
||||
Message = _auth.IsConfigured ? "configured" : "not-configured"
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user