헤더 체크
- 요청 헤더에 설정된 API-KEY 값을 검증하는 필터를 개발한다.
- 헤더의 키 값으로 X-API-KEY 을 사용한다.
- 데이터베이스 테이블에서 값을 조회하여 API-KEY 값을 검증한다.
- API-KEY 값이 데이터베이스에 없는 경우에는 401 UNAUTHORIZED 값을 반환한다.
@Slf4j@Component@RequiredArgsConstructorpublic class ApiKeyAuthFilter implements Filter { private final UniqueIdService uniqueIdService;
private final ObjectMapper objectMapper = new ObjectMapper();
@Override public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain ) throws IOException, ServletException { final String apiKey = ServletUtil.getHeaderValue("X-API-KEY"); if (StringUtils.isNotBlank(apiKey)) { final int count = uniqueIdService.selectUniqueIdCnt(apiKey); log.debug("count: {}", count);
if (count< 1) { setResponse((HttpServletResponse) response); return; } } chain.doFilter(request, response); }
private void setResponse(final HttpServletResponse response) throws IOException { response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); response.setContentType("application/json;charset=UTF-8");
final ResponseDto<Void> responseDto = new ResponseDto<>(); responseDto.setSuccessYn("N"); responseDto.setMessageCd("INVALID_API_KEY");
final String jsonString = objectMapper.writeValueAsString(responseDto); response.getWriter().write(jsonString); }}@Beanpublic FilterRegistrationBean<ApiKeyAuthFilter> loggingFilter(final UniqueIdService uniqueIdService) { FilterRegistrationBean<ApiKeyAuthFilter> registrationBean = new FilterRegistrationBean<>(new ApiKeyAuthFilter(uniqueIdService)); registrationBean.addUrlPatterns("/v1/*"); // 특정 URL 패턴 적용 registrationBean.setOrder(1); // 순서 설정 return registrationBean;}@DisplayName("헤더 값 체크")@Testvoid testHeaderCheck() { final SearchUserConditionRequest param = SearchUserConditionRequest.builder() .build(); given() .spec(jsonRequestSpecification) .header("X-API-KEY", "1234") .body(param) .when() .post("/spring-boot/multi-value-validation-test") .then() .statusCode(HttpStatus.SC_UNAUTHORIZED) .body( "successYn", equalTo("N"), "messageCd", equalTo("INVALID_API_KEY"), "payload", nullValue() ) .log().all();}2026-02-26 10:38:07,763 [DEBUG] [http-nio-auto-1-exec-7] o.a.i.l.j.BaseJdbcLogger: ==> Preparing: /*selectUniqueIdCnt*/ SELECT COUNT(0) AS CNT FROM UNIQUE_ID WHERE UNIQUE_ID = ? AND USE_YN = 'Y'2026-02-26 10:38:07,763 [DEBUG] [http-nio-auto-1-exec-7] o.a.i.l.j.BaseJdbcLogger: ==> Parameters: 1234(String)2026-02-26 10:38:07,767 [DEBUG] [http-nio-auto-1-exec-7] n.s.l.l.s.Slf4jSpyLogDelegator: com.zaxxer.hikari.pool.ProxyPreparedStatement.execute(ProxyPreparedStatement.java:44)1. /*selectUniqueIdCnt*/SELECT COUNT(0) AS CNT FROM UNIQUE_ID WHERE UNIQUE_ID = '1234' AND USE_YN = 'Y' {executed in 3 msec}2026-02-26 10:38:07,767 [INFO ] [http-nio-auto-1-exec-7] n.s.l.l.s.Slf4jSpyLogDelegator:|----||cnt ||----||0 ||----|
2026-02-26 10:38:07,768 [DEBUG] [http-nio-auto-1-exec-7] o.a.i.l.j.BaseJdbcLogger: <== Total: 12026-02-26 10:38:07,772 [DEBUG] [http-nio-auto-1-exec-7] c.e.s.c.f.ApiKeyAuthFilter: count: 0HTTP/1.1 401X-Content-Type-Options: nosniffX-XSS-Protection: 0Cache-Control: no-cache, no-store, max-age=0, must-revalidatePragma: no-cacheExpires: 0X-Frame-Options: DENYContent-Type: application/json;charset=UTF-8Content-Length: 62Date: Thu, 26 Feb 2026 01:38:07 GMTKeep-Alive: timeout=60Connection: keep-alive
{ "payload": null, "successYn": "N", "messageCd": "INVALID_API_KEY"}