Post

[TIL] 개인 프로젝트 - 'Spring Plus' 후기

[TIL] 개인 프로젝트 - 'Spring Plus' 후기

1. 스프링 플러스 주차 개인 과제

이번 개인 프로젝트에서 진행했던 부분은 그렇게 어려운 편이 많지는 않았으나…
외적으로 조금 바쁘게 지냈던 탓에 사실 진행을 거의 못했습니다

정작 중요한 AWS, Docker, Kotlin을 배우지 못했지만 오늘 개인 프로젝트를 마무리 한 뒤 써봐야겠습니다
곧 후술할 새롭게 배운 내용들은 간략하게 작성되었으며, 보다 자세한 내용은 조만간 새로 글을 작성하겠습니다



2. 새롭게 배운 내용들

2-1. AOP (Aspect-Oriented Programming)

@Aspect를 통해 관점 지향 프로그래밍을 할 수 있습니다
어플리케이션에서 여러 부분에 반복적으로 사용되는 기능을 하나의 장소에 관리하는 것이라 볼 수 있습니다

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// AdminAcessLoggingAspect.java
@Aspect
@Component
@RequiredArgsConstructor
public class AdminAccessLoggingAspect {

    private final HttpServletRequest request;

    // UserAdminController의 changeUserRole 메서드가 실행되기 전에 작동하도록 설정
    @Before("execution(* org.example.expert.domain.user.controller.UserAdminController.changeUserRole(..))")
    public void logBeforeChangeUserRole(JoinPoint joinPoint) {

        String userId = String.valueOf(request.getAttribute("userId"));
        String requestUrl = request.getRequestURI();
        LocalDateTime requestTime = LocalDateTime.now();

        log.info("Admin Access Log - User ID: {}, Request Time: {}, Request URL: {}, Method: {}",
                userId, requestTime, requestUrl, joinPoint.getSignature().getName());
    }
}
  • excution(...) : UserAdminControllerchangeUserRole 메서드가 실행될 경우 작동합니다
  • @Before : changeUserRole 메서드가 실행되기 전에 logBeforeChangeUserRole 메서드가 작동됩니다

이번 개인 프로젝트에서 사용된 내용은 일부이며, @After, JoginPoint 등 더 다양하게 사용할 수 있습니다

아무튼, 지금은 execution을 통해 어느 메서드라고 지정하긴 했지만 직접 어노테이션 인터페이스를 만든 뒤
사용하고 싶은 메서드에 부착하며 지정하는 것도 가능합니다



2-2. QueryDSL

DSL : Domain Specific Language : 쿼리 생성에 특화된 언어

QueryDSL은 직접 @Query 등을 사용하여 쿼리를 작성하는 대신, 자바에서 안전하게 쿼리를 작성하게 도와주는 라이브러리입니다

1
2
3
4
5
6
7
8
9
QUser user = QUser.user;

// name이 null이 아니면 검색 -> optional 조건 활용 가능
BooleanExpression pred = name != null ? user.name.eq(name) : null;

// QueryDSL 기반 검색
List<User> users = queryFactory.selectFrom(user)
                                .where(pred)
                                .fetch();

DSL을 사용하면서 컴파일 시점에서 오류를 확인할 수 있기에 더욱 안전하게 쿼리를 작성할 수 있습니다
그리고 동적 조건을 조합하기도 유용하고 Join이나 OrderBy 등, 다양한 쿼리를 지원합니다



2-3. Spring Security

Spring Security는 인증(Authentication), 인가(Authorization)를 관리하는 보안 프레임워크입니다
이번 프로젝트에서는 로그인한 사용자 인증 처리, 권한에 따른 처리로 사용되었습니다

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public SecurityFilterChain securityFilterChain(HttpSecurity http, JwtFilter jwtFilter) throws Exception {

    return http
            .csrf(AbstractHttpConfigurer::disable)  // JWT 토큰 인증시 서버가 세션을 저장하지 않으므로 CSRF(Cross-Site Request Forgery) 보호 해제

            .authorizeHttpRequests(authRequest -> authRequest
                    .requestMatchers("/auth/**").permitAll()        // auth : 누구나 접근 가능 (로그인 필요 X)
                    .requestMatchers("/admin/**").hasRole("ADMIN")  // admin : ADMIN 권한 사용자만 접근 가능
                    .anyRequest().authenticated())                    // auth, admin을 제외한 요청 -> authenticated 사용자만 접근 가능

            .httpBasic(AbstractHttpConfigurer::disable)     // 브라우저 팝업 방식 비활성화
            .logout(AbstractHttpConfigurer::disable)        // 세션 로그아웃 기능 비활성화
            .rememberMe(AbstractHttpConfigurer::disable)    // 자동 로그인 쿠키 발급 기능 비활성화
            .formLogin(AbstractHttpConfigurer::disable)     // 토큰 발급이므로 세션 인증을 처리하는 formLogin 비활성화
            .anonymous(AbstractHttpConfigurer::disable)     // JWT 기반 API 에서 인증이 없으면 401로 처리하므로 비활성화

            // exceptionHandling이 필요한 경우 사용
            // .exceptionHandling(exception -> exception
            //         .authenticationEntryPoint(토큰이 없거나 잘못된 처리인 경우)
            //         .accessDeniedHandler(권한이 부족한 경우))

            .addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class)     // 로그인 인증 필터 실행 전 JwtFilter 작동
            .build();
}
This post is licensed under CC BY 4.0 by the author.