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

[BE] 사용자 인증 Interceptor 개선 #306

Closed
jaejae-yoo opened this issue Aug 29, 2022 · 0 comments · Fixed by #307
Closed

[BE] 사용자 인증 Interceptor 개선 #306

jaejae-yoo opened this issue Aug 29, 2022 · 0 comments · Fixed by #307
Assignees
Labels
🖥 backend New backend feature 🛠 refactoring Refactor code
Milestone

Comments

@jaejae-yoo
Copy link
Collaborator

jaejae-yoo commented Aug 29, 2022

요약

현재 문제점

  1. 인증이 필요한 요청이 많이 증가하였고, 많은 (인증)요청 url들을 텍스트로 관리하다 보니, 구현 및 테스트를 작성하는 과정에서 실수하는 일이 늘어났습니다.
  2. 로그인 인터셉터에서 처리하지 않아도 되는 로직이 포함되어 검증 로직과 섞여 있습니다.

요약

  1. PathMatcherInterceptor 생성
  2. AuthenticationInterceptor 개선

세부사항

개선 사항

AS-IS

  1. API가 늘어남에 따라, 인증이 필요한 요청을 관리하는 것이 매우 어려워 졌습니다.
    → 따라서 많은 (인증)요청 url들을 텍스트로 관리하다 보니, 구현 및 테스트를 작성하는 과정에서 실수하는 일이 늘어났습니다.
@Bean
public AuthenticationRequestMatcher authenticationRequestMatcher() {
        return new AuthenticationRequestMatcherBuilder()
                .addUpAuthenticationPath(POST,
                        "/api/studies/\\d+/reviews",
                        "/api/studies/\\d+/reviews/\\d+",
                        "/api/studies/\\w+/\\w+/articles",
                        "/api/studies")
                .addUpAuthenticationPath(GET,
                        "/api/my/studies",
                        "/api/auth/refresh",
                        "/api/members/me",
                        "/api/members/me/role",
                        "/api/studies/\\w+/community/articles/\\w+",
                        "/api/studies/\\w+/community/articles",
                        "/api/studies/\\d+/reference-room/links"
                )
                .addUpAuthenticationPath(HttpMethod.PUT,
                        "/api/studies/\\d+/reviews/\\d+",
                        "/api/studies/\\d+/reference-room/links/\\d+",
                        "/api/study/\\d+"
                )
                .addUpAuthenticationPath(HttpMethod.DELETE,
                        "/api/studies/\\d+/reviews/\\d+",
                        "/api/studies/\\w+/\\w+/articles/\\w+")
                .build();
}

TO-BE

private HandlerInterceptor loginInterceptor() {
        return new PathMatcherInterceptor(new AuthenticationInterceptor(jwtTokenProvider), pathMatcherContainer)
                .excludePathPattern("/**", HttpMethod.OPTIONS)
                .includePathPattern("/api/studies/**", HttpMethod.POST)
                .includePathPattern("/api/studies/**", HttpMethod.PUT)
                .includePathPattern("/api/study/\\d+", HttpMethod.PUT)
                .includePathPattern("/api/studies/**", HttpMethod.DELETE)
                .includePathPattern("/api/members/me/**", HttpMethod.GET)
                .includePathPattern("/api/auth/refresh", HttpMethod.GET)
                .includePathPattern("/api/my/studies", HttpMethod.GET)
                .includePathPattern("/api/studies/\\w+/community/articles/**", HttpMethod.GET)
                .includePathPattern("/api/studies/\\d+/reference-room/links", HttpMethod.GET);
}

AuthenticationInterceptor를 PathMatcherInterceptor로 감싸서, 인증 요청이 필요한 url과 요청을 묶어서 간결하게 처리할 수 있도록 개선했습니다.

if (authenticationRequestMatcher.isRequiredAuth(request)) {
    //...
}

따라서 기존의 AuthenticationInterceptor에서 인증이 필요한 로직인지 판별했던 로직을 제거하였고,
PathMatcherInterceptor에서 인증이 필요한 요청을 판단한 후, 인증이 필요하다면 AuthenticationInterceptor의 preHandle 메서드를 호출하도록 개선했습니다.


AS-IS

  1. preflight를 확인하는 로직이 AuthenticationInterceptor에 존재하고 있었습니다.
@Override
public boolean preHandle(final HttpServletRequest request, final HttpServletResponse response, final Object handler) {
        
        if (isPreflight(request)) {
            return true;
        }

        if (authenticationRequestMatcher.isRequiredAuth(request)) {
            final String token = AuthenticationExtractor.extract(request);
            validateToken(token, request.getRequestURI());

            request.setAttribute("payload", token);
        }

        return true;
}

TO-BE

AuthenticationInterceptor.class

@Override
public boolean preHandle(final HttpServletRequest request, final HttpServletResponse response, final Object handler) {
        final String token = AuthenticationExtractor.extract(request);
        validateToken(token, request.getRequestURI());

        request.setAttribute("payload", token);
        return true;
}

PathMatcherInterceptor.class

@Override
public boolean preHandle(final HttpServletRequest request, final HttpServletResponse response, final Object handler)
            throws Exception {

        if (pathMatcherContainer.isNotIncludePath(request.getRequestURI(), request.getMethod())) {
            return true;
        }

        return this.handlerInterceptor.preHandle(request, response, handler);
}

AuthenticationInterceptor은 검증을 하는 역할만 수행하도록 하고, PathMatcherInterceptor에서 preflight 요청 확인 및 인증이 필요한 경우 AuthenticationInterceptor를 호출하도록 개선했습니다.

@jaejae-yoo jaejae-yoo added 🖥 backend New backend feature 🛠 refactoring Refactor code labels Aug 29, 2022
@jaejae-yoo jaejae-yoo self-assigned this Aug 29, 2022
@tco0427 tco0427 added this to the Milestone 5 milestone Sep 13, 2022
@nan-noo nan-noo linked a pull request Sep 14, 2022 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🖥 backend New backend feature 🛠 refactoring Refactor code
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants