Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: 중복 요청 방지를 위한 AOP 설정 #335

Merged
merged 1 commit into from
Sep 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ public enum ExceptionCode {
// 4xx
UNAUTHORIZED(401, "유효하지 않은 토큰 "),
NOT_FOUND(404, "존재하지 않음 "),
TOO_MANY_REQUESTS(429, "너무 많은 요청"),

// 5xx
SERVICE_AVAILABLE(503, "서비스에 접근할 수 없음 "),
Expand Down
3 changes: 3 additions & 0 deletions smeem-input-http/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ project(':smeem-input-http') {
implementation group: 'io.jsonwebtoken', name: 'jjwt-api', version: '0.11.5'
implementation group: 'io.jsonwebtoken', name: 'jjwt-impl', version: '0.11.5'
implementation group: 'io.jsonwebtoken', name: 'jjwt-jackson', version: '0.11.5'

// AOP
implementation 'org.springframework.boot:spring-boot-starter-aop'
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package com.smeem.http.aspect;

import com.smeem.common.exception.ExceptionCode;
import com.smeem.http.controller.dto.ExceptionResponse;
import lombok.val;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

@Aspect
@Component
public class DuplicateRequestAspect {
private final Set<String> requestSet = Collections.synchronizedSet(new HashSet<>());

@Pointcut("within(*..*Api)")
public void onRequest() {
}

@Around("onRequest()")
public Object duplicateRequestCheck(ProceedingJoinPoint joinPoint) throws Throwable {
val request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
val httpMethod = request.getMethod();

// GET 요청일 경우 중복 체크 생략
if ("GET".equalsIgnoreCase(httpMethod)) {
return joinPoint.proceed();
}

val requestId = joinPoint.getSignature().toLongString();
if (requestSet.contains(requestId)) {
// 중복 요청인 경우
return handleDuplicateRequest();
}
requestSet.add(requestId);

try {
return joinPoint.proceed();
} finally { // 요청 후 요청값 삭제
requestSet.remove(requestId);
}
}

private ResponseEntity<ExceptionResponse> handleDuplicateRequest() {
return ResponseEntity
.status(ExceptionCode.TOO_MANY_REQUESTS.getStatusCode())
.body(ExceptionResponse.of(ExceptionCode.TOO_MANY_REQUESTS.getMessage() + ": 중복된 요청"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import com.smeem.application.port.input.BadgeUseCase;
import com.smeem.http.controller.dto.SmeemResponse;
import com.smeem.application.port.input.dto.response.badge.RetrieveMemberBadgesResponse;
import com.smeem.http.controller.docs.MemberBadgeApiV3Docs;
import com.smeem.http.controller.docs.MemberBadgeV3ApiDocs;
import com.smeem.common.util.SmeemConverter;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
Expand All @@ -18,7 +18,7 @@
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/v3/members/badges")
public class MemberBadgeApiV3 implements MemberBadgeApiV3Docs {
public class MemberBadgeV3Api implements MemberBadgeV3ApiDocs {
private final BadgeUseCase badgeUseCase;
private final SmeemConverter smeemConverter;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import java.security.Principal;

@Tag(name = "MemberBadgeApi (v3)", description = "회원의 배지(Badge) 관련 Api 입니다.")
public interface MemberBadgeApiV3Docs {
public interface MemberBadgeV3ApiDocs {

@Operation(summary = "배지 조회 api", description = "회원의 배지 정보를 조회합니다.")
@ApiResponses(value = {
Expand Down
Loading