[] API Header 점검하는 로직 추가 중

This commit is contained in:
김선규 2025-03-18 17:54:04 +09:00
parent cb159397af
commit 50f740aa4b
6 changed files with 127 additions and 6 deletions

View File

@ -18,9 +18,5 @@
<PackageReference Include="Swashbuckle.AspNetCore.Annotations" Version="7.1.0" />
</ItemGroup>
<ItemGroup>
<Folder Include="Program\Common\Interfaces\" />
</ItemGroup>
</Project>

View File

@ -14,6 +14,7 @@ using System.Text.Json;
using AcaMate.Common.Models;
using AcaMate.V1.Services;
using AcaMate.Common.Data;
using AcaMate.Common.Token;
using AcaMate.V1.Controllers;
using AcaMate.V1.Models;
@ -149,10 +150,13 @@ else
builder.Logging.SetMinimumLevel(LogLevel.Warning);
}
//헤더 부분
builder.Services.AddScoped<IHeaderConfig, HeaderConfigRepository>();
// 로컬 테스트 위한 부분 (올릴때는 꺼두기)
// builder.WebHost.UseUrls("http://0.0.0.0:5144");
builder.WebHost.UseUrls("http://0.0.0.0:5144");
///// ===== builder 설정 부 ===== /////
@ -172,7 +176,14 @@ else
}
// 로컬 테스트 위한 부분 (올릴떄는 켜두기)
app.UseHttpsRedirection();
// app.UseHttpsRedirection();
// 헤더 미들웨어 부분
app.UseMiddleware<APIHeaderMiddle>("HEAD-CHECK");
// 이부분 봐야 합니다.
// app.UseMiddleware<CustomHeaderMiddleware>("X-MyHeader");
app.UseRouting();
// app.MapControllers();

View File

@ -0,0 +1,27 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
namespace AcaMate.Common.Token;
public class APIHeaderFilter : ActionFilterAttribute
{
private readonly string _headerName;
public APIHeaderFilter(string headerName)
{
_headerName = headerName;
}
public override void OnActionExecuted(ActionExecutedContext context)
{
if (!context.HttpContext.Request.Headers.TryGetValue(_headerName, out var headerValues) ||
string.IsNullOrWhiteSpace(headerValues))
{
context.Result = new BadRequestObjectResult($"Missing or empty header: {_headerName}");
}
base.OnActionExecuted(context);
}
}

View File

@ -0,0 +1,65 @@
using System.Threading.Tasks;
using AcaMate.Common.Data;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
namespace AcaMate.Common.Token;
public interface IHeaderConfig
{
Task<string> GetExpectedHeaderValueAsync(string headerName);
}
public class HeaderConfigRepository : IHeaderConfig
{
private readonly AppDbContext _dbContext;
public HeaderConfigRepository(AppDbContext dbContext)
{
_dbContext = dbContext;
}
public async Task<string> GetExpectedHeaderValueAsync(string headerName)
{
// 예를 들어, HeaderConfig 테이블에 헤더 이름과 기대 값이 저장되어 있다고 가정합니다.
var config = await _dbContext.APIHeader.
FirstOrDefaultAsync(h => h.h_key == headerName);
return config?.h_value ?? string.Empty;
}
}
public class APIHeaderMiddle
{
private readonly RequestDelegate _next;
private readonly string _headerName;
private readonly IHeaderConfig _headerConfig;
public APIHeaderMiddle(RequestDelegate next, string headerName, IHeaderConfig headerConfig)
{
_next = next;
_headerName = headerName;
_headerConfig = headerConfig;
}
public async Task Invoke(HttpContext context)
{
var expectedValue = await _headerConfig.GetExpectedHeaderValueAsync(_headerName);
if (!context.Request.Headers.TryGetValue(_headerName,out var headerValue) || string.IsNullOrWhiteSpace(headerValue))
// if (!context.Request.Headers.ContainsKey(_headerName) || string.IsNullOrWhiteSpace(context.Request.Headers[_headerName]))
{
context.Response.StatusCode = StatusCodes.Status400BadRequest;
await context.Response.WriteAsync($"Missing or empty header: {_headerName}");
return;
}
if (headerValue != expectedValue)
{
context.Response.StatusCode = StatusCodes.Status401Unauthorized;
await context.Response.WriteAsync($"Invalid header value");
return;
}
await _next(context);
}
}

View File

@ -11,6 +11,9 @@ public class AppDbContext: DbContext
{
}
//MARK: API
public DbSet<APIHeader> APIHeader { get; set; }
//MARK: Program
public DbSet<Version> Version { get; set; }
public DbSet<Academy> Academy { get; set; }

View File

@ -0,0 +1,19 @@
using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel.DataAnnotations;
namespace AcaMate.Common.Models;
[Table("api_header")]
public class APIHeader
{
[Key]
public string h_key { get; set; }
public string h_value { get; set; }
}
/*
h_key : h_value
iOS_AM_Connect_Key
And_AM_Connect_Key
Web_AM_Connect_Key
*/