SPMS_API/SPMS.API/Middlewares/ApiKeyMiddleware.cs
SEAN df8a8e2e5b feat: X-Service-Code / X-API-KEY 서비스 식별 미들웨어 구현 (#32)
- ServiceRepository: IServiceRepository 구현 (GetByServiceCode, GetByApiKey)
- ServiceCodeMiddleware: X-Service-Code 헤더 검증, DB 조회, 서비스 상태 확인
- ApiKeyMiddleware: /v1/in/device/* 경로 X-API-KEY 검증
- ApplicationBuilderExtensions: 미들웨어 파이프라인 12~13번 등록
- DependencyInjection: IServiceRepository DI 등록

Closes #32
2026-02-09 17:25:19 +09:00

50 lines
1.5 KiB
C#

using SPMS.Domain.Common;
using SPMS.Domain.Interfaces;
namespace SPMS.API.Middlewares;
public class ApiKeyMiddleware
{
private readonly RequestDelegate _next;
public ApiKeyMiddleware(RequestDelegate next) => _next = next;
public async Task InvokeAsync(HttpContext context, IServiceRepository serviceRepository)
{
if (!RequiresApiKey(context.Request.Path))
{
await _next(context);
return;
}
if (!context.Request.Headers.TryGetValue("X-API-KEY", out var apiKey) ||
string.IsNullOrWhiteSpace(apiKey))
{
context.Response.StatusCode = 401;
context.Response.ContentType = "application/json";
await context.Response.WriteAsJsonAsync(
ApiResponse.Fail(ErrorCodes.Unauthorized, "API Key가 필요합니다."));
return;
}
var service = await serviceRepository.GetByApiKeyAsync(apiKey!);
if (service == null)
{
context.Response.StatusCode = 403;
context.Response.ContentType = "application/json";
await context.Response.WriteAsJsonAsync(
ApiResponse.Fail(ErrorCodes.Unauthorized, "유효하지 않은 API Key입니다."));
return;
}
context.Items["Service"] = service;
context.Items["ServiceId"] = service.Id;
await _next(context);
}
private static bool RequiresApiKey(PathString path)
{
return path.StartsWithSegments("/v1/in/device");
}
}