[성현모] AuthApi 분리

This commit is contained in:
SHM
2025-07-15 10:16:26 +09:00
parent 20f1e7e7e5
commit 7a12be392a
52 changed files with 1931 additions and 60 deletions

View File

@ -0,0 +1,146 @@
using AuthApi.Services;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using SystemX.Core;
using SystemX.Core.Model.Auth;
namespace AuthApi.Controllers
{
[Tags("Auth")]
[Route("api/auth")]
[ApiController]
[ApiExplorerSettings(IgnoreApi = true)]
public class AuthController : CommonController
{
private readonly AuthService _authService;
public AuthController(IServiceProvider serviceProvider, IHttpContextAccessor httpContextAccessor,
AuthService authService)
: base(serviceProvider, httpContextAccessor)
{
_authService = authService;
}
[HttpGet("/health")]
public async Task<IResult> Health()
{
await Task.CompletedTask;
return Results.Ok("Healthy");
}
[HttpPost("regisger")]
public async Task<IResult> Register([FromBody] RegisterModel request)
{
// Log4net.WriteLine(GetRequestLog(request).LogModelToString("Request Auth"), LogType.CONTROLLER);
RegisterResponseModel response = new RegisterResponseModel();
if (request?.UserID != null && request?.Password != null)
{
response = await _authService.CreateUser(request);
}
// Log4net.WriteLine(GetResponseLog(response).LogModelToString("Response Auth"), LogType.CONTROLLER);
return Results.Ok(response);
}
[HttpPost("login")]
public async Task<IResult> Login([FromBody] LoginModel request)
{
// Log4net.WriteLine(GetRequestLog(request).LogModelToString("Request Auth"), LogType.CONTROLLER);
LoginResponseModel response = new LoginResponseModel();
response.UserID = request.UserID;
response.EC = ERROR_CODE.EC_USER_LOGIN_FAILED;
if (request.UserID != null && request.Password != null)
{
response = await _authService.SelectUser(request);
if (response.EC == ERROR_CODE.EC_OK)
{
double convertExpires = Convert.ToDouble(_configService?.GetConfig()?.Auth?.accessTokenExpires);
response.AccessToken = GenerateJwtToken(response);
response.AccessTokenExpired = DateTime.UtcNow.AddMinutes(convertExpires).ToUnixTime();
response.RefreshToken = GenerateJwtToken(response, true);
}
await _authService.UpdateLoginInfo(request, response.RefreshToken);
}
// Log4net.WriteLine(GetResponseLog(response).LogModelToString("Response Auth"), LogType.CONTROLLER);
return Results.Ok(response);
}
[HttpPost("logout")]
public async Task<IResult> Logout([FromBody] LogoutModel request)
{
// Log4net.WriteLine(GetRequestLog(request).LogModelToString("Request Auth"), LogType.CONTROLLER);
var response = _authService.LogoutUser(request);
await Task.CompletedTask;
// Log4net.WriteLine(GetResponseLog(response).LogModelToString("Response Auth"), LogType.CONTROLLER);
return Results.Ok(response);
}
[Authorize]
[HttpPost("validate")]
public ActionResult<string> Validate([FromBody] string authToken)
{
return "";
}
private TokenValidationParameters GetValidationParameters()
{
return new TokenValidationParameters()
{
ValidateLifetime = true,
ValidateAudience = true,
ValidateIssuer = true,
ValidIssuer = $"{_configService?.GetConfig()?.Auth?.issuer}",
ValidAudience = $"{_configService?.GetConfig()?.Auth?.issuer}",
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes($"{_configService?.GetConfig()?.Auth?.accessTokenSecret}"))
};
}
private string GenerateJwtToken(LoginResponseModel loginResponseModel, bool isRefreshToken = false)
{
var claims = new[]
{
new Claim(ClaimTypes.Name, $"{loginResponseModel.UserID}"),
new Claim(ClaimTypes.Role, $"{loginResponseModel.RoleName}"),
};
string secret = $"{_configService?.GetConfig()?.Auth?.accessTokenSecret}";
double convertExpires = Convert.ToDouble(_configService?.GetConfig()?.Auth?.accessTokenExpires);
if (isRefreshToken == true)
{
secret = $"{_configService?.GetConfig()?.Auth?.refreshTokenSecret}";
convertExpires = Convert.ToDouble(_configService?.GetConfig()?.Auth?.refreshTokenExpires);
}
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secret));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var token = new JwtSecurityToken(
issuer: $"{_configService?.GetConfig()?.Auth?.issuer}",
audience: $"{_configService?.GetConfig()?.Auth?.audience}",
claims: claims,
expires: DateTime.UtcNow.AddMinutes(convertExpires),
signingCredentials: creds
);
return new JwtSecurityTokenHandler().WriteToken(token);
}
}
}

View File

@ -0,0 +1,59 @@
using Microsoft.AspNetCore.Mvc;
using System.Runtime.CompilerServices;
using SystemX.Core.Services;
using WebApi.Library.Config;
namespace AuthApi.Controllers
{
public class CommonController : ControllerBase
{
public readonly IServiceProvider _serviceProvider;
public readonly IHttpContextAccessor _httpContextAccessor;
public readonly ConfigService<WebApiConfig>? _configService;
protected static Guid guid { get; private set; } = Guid.NewGuid();
public CommonController(IServiceProvider serviceProvider, IHttpContextAccessor httpContextAccessor)
{
//provider
_serviceProvider = serviceProvider;
_httpContextAccessor = httpContextAccessor;
//service
_configService = _serviceProvider.GetService<ConfigService<WebApiConfig>>();
}
/// <summary>
/// Request 클라이언트 IP
/// </summary>
protected virtual string? GetClientIP()
{
return _httpContextAccessor?.HttpContext?.Connection?.RemoteIpAddress?.ToString();
}
/// <summary>
/// Request 클라이언트 Url
/// </summary>
protected virtual string? GetRequestUrl()
{
return _httpContextAccessor?.HttpContext?.Request?.Path;
}
/// <summary>
/// Request 클라이언트 method: [GET] or [POST]
/// </summary>
protected virtual string? GetRequestMethod()
{
return _httpContextAccessor?.HttpContext?.Request?.Method;
}
/// <summary>
/// 현재 Action(함수) 이름 가져오기
/// </summary>
protected virtual string GetMethodName([CallerMemberName] string callerMemberName = "")
{
return callerMemberName;
}
}
}

View File

@ -1,33 +0,0 @@
using Microsoft.AspNetCore.Mvc;
namespace AuthApi.Controllers
{
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
private readonly ILogger<WeatherForecastController> _logger;
public WeatherForecastController(ILogger<WeatherForecastController> logger)
{
_logger = logger;
}
[HttpGet(Name = "GetWeatherForecast")]
public IEnumerable<WeatherForecast> Get()
{
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
})
.ToArray();
}
}
}