다른 페이지에 접속할 때마다 계속해서 로그인을 반복을 방지하기 위해서 로그인 체크 기능 AOP를 적용하였습니다.
AOP
AOP란 관점 지향 프로그래밍으로 흩어진 공통점을 모아 만든 관점을 의미합니다.
@Aspect를 사용하면 AOP를 구현할 수 있기 때문에 반복되는 코드들을 정리할 수 있습니다.
또한 재사용 용이하며, 코드 누락 위험성이 적어집니다.
@Aspect
@Component
@Order(Ordered.LOWEST_PRECEDENCE)
@Log4j2
@SuppressWarnings("unchecked")
public class AuthCheckAspect {
@Autowired
private UserService userService;
@Around("@annotation(com.idolticketing.idolticketing.aop.LoginCheck) && @ annotation(loginCheck)")
public Object UserLoginCheck(ProceedingJoinPoint jp, LoginCheck loginCheck) throws Throwable {
log.debug("AOP - User Login Check Started");
Object[] signatureArgs = jp.getArgs();
HttpSession session = ((ServletRequestAttributes) (RequestContextHolder.currentRequestAttributes())).getRequest().getSession();
String sessionUserId = null;
boolean isAdmin = false;
}
@Component
스프링으로 자동 관리를 해주기위해서 빈으로 등록하는 어노테이션입니다.
@Around
joinpoint에 Advice가 삽입되는데 Advice에는 5가지 시점(@After, @AfterReturning, @AfterThrowing, @Around, @Before )이 존재합니다. 그 중 Around에는 메소드 호출 자체를 가로채서 비즈니스 메소드 실행 전,후 모두에 처리할 로직을 삽입 할 수 있습니다.
저는 LoginCheck를 할 시 메소드 호출를 가로챌 수 있도록 만들었고, 세션 값과 isAdmin 값을 설정하였습니다.
@log4j2
logging이란 어떤 이벤트가 발생했을 때 로그가 남는 것을 의미합니다. 이 어노테이션을 사용하면 로그인기록이 남아 로그인이 되었는지를 확인할 수 있습니다.
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface LoginCheck {
public static enum Role{
USER,ADMIN
}
Role type();
}
열거형인 enum을 사용하면 말 그대로 열거가 된다는 뜻입니다.
USER = 0, ADMIN = 1이 설정되었습니다.
@PostMapping("")
@ResponseStatus(HttpStatus.CREATED)
@LoginCheck(type = LoginCheck.Role.USER)
public ResponseEntity<?> createBook(String userId, boolean isAdmin,
@RequestBody BookDTO bookDTO,
@ApiParam(value = "lang", defaultValue = "ko") @RequestParam String lang) {
if (userId.equals(bookDTO.getUserId())) {
bookService.createBook(bookDTO);
} else {
return new ResponseEntity<>("잘못된 접근입니다.", HttpStatus.BAD_REQUEST);
}
return new ResponseEntity<>(bookDTO, HttpStatus.OK);
}
Book Controller에 와서 LoginCheck를 확인해 보면
@LoginCheck를 통해 @Around가 createBook 메소드가 호출되기 전 가로채 LoginCheck 메소드를 호출합니다.
타입은 Login.Role.USER로 설정되어 있어서 유저로 인식하게 됩니다.
이번에 로그인 체크 AOP를 다루면서 시점에 대해 자세히 공부할 수 있어서 좋았습니다.
joinpoint에 대해 매번 헷갈렸었는데 joinpoint에 Advice(시점이 있는)가 삽입되기 때문에 왜 joinpoint가 먼저와야 하는지에 대해 이해가 잘되어서 유용했습니다.
'PROJECT > 티켓팅 서버 프로젝트' 카테고리의 다른 글
Custom Exception 적용하기 (0) | 2022.11.01 |
---|---|
MVC 패턴 Controller 적용하기 (0) | 2022.10.05 |
Jenkins CI/CD 적용하기 (0) | 2022.09.20 |
locust 성능 테스트 시나리오 (0) | 2022.08.29 |
Junit 테스트코드(Junit5와 Junit4의 차이) (0) | 2022.07.18 |