Project/TDD

[TDD] Filter를 통해 사용자의 Repo를 감시하자.

EJUN 2024. 9. 8. 15:03

TDD프로젝트의 구현을 마치고 앱스토어에 무려 1트만에 배포가 성공되어서 너무 기뻤다..ㅎㅎㅎㅎㅎ

 

이제 배포를 하고 문제점을 찾아가던 중 생각보다 치명적인 버그가 있었다.

우리 서비스는 Todo를 등록하면 자동으로 사용자가 등록한 github repo의 README와 issue에 등록이 되는 서비스인데 만약 사용자가 깃허브에서 repo를 삭제하면 바로 버그가 생기는 것이다...

 

왜냐면 DB에는 사용자의 repo정보가 남아있는데 정작 깃허브에는 해당 레포가 없기 때문에 깃허브 repo READMD와 issue를 등록할 수 없기 때문이다..(물론 저 부분도 분리를 해야하는데 추후에 작업을 해보자,,,)

 

그래서 저 문제를 해결하기 위해 우선 webhook을 등록해서 사용자가 깃허브에서 repo를 삭제하면 자동으로 DB에서도 삭제되게끔 동작을 해두었다.(null처리로,,ㅎ)

하지만 여기서 문제가 현재 우리가 사용자가 깃허브 유무를 확인하는 부분은 앱을 킬 때와 로그인 유무를 확인한 후 만 검사를 진행한다.

만약 사용자가 앱을 끄지 않고 사용 중에 깃허브에서 repo를 삭제한다면,,,,바로 500에러가 터질 것이다.

 

빠르게 이 문제를 해결해야 했고, 바로 든 생각은 인증이 필요한 부분에서 매번 인증하는 메소드를 호출하는 것이다.

fun isExistRepo(name: String) =
    memberReader.getMember(name).gitHubRepo
        ?: throw ToDeveloperDoException { "not existed Repo }

뭐 대충 예를 들어 저런 코드가 매번 호출된다라고 생각하면 된다.

 

이 방법을 하면 사실 제일 간단하고 위 문제를 해결할 수 있는 방법이긴하다.

하지만 이는 아마추어인 내가 봐도 너무 무식해보이는 방식이어서 pass...

 

[출처] : https://www.google.com/url?sa=i&url=https%3A%2F%2Fnamu.wiki%2Fw%2F%25EC%259E%2598%2520%25EB%25AA%25A8%25EB%25A5%25B4%25EA%25B3%25A0%2520%25EB%25AC%25B4%25EC%258B%259D%25ED%2595%259C%2520%25EC%2582%25AC%25EB%259E%258C%25EC%259D%25B4%2520%25EC%258B%25A0%25EB%2585%2590%25EC%259D%2584%2520%25EA%25B0%2580%25EC%25A7%2580%25EB%25A9%25B4%2520%25EB%25AC%25B4%25EC%2584%25AD%25EC%258A%25B5%25EB%258B%2588%25EB%258B%25A4&psig=AOvVaw24Xq5Z4CvKdWAoRPkSQs_b&ust=1725860493097000&source=images&cd=vfe&opi=89978449&ved=0CBQQjRxqFwoTCMCx29PRsogDFQAAAAAdAAAAABAE

 

 

그러다 문득 우리가 로그인을 하고 인증이 필요한 API를 호출할 때 마다 JWT filter에서 검사를 하고 있는 것이 떠올랐다.

어차피 우리도 JWT토큰을 검증하는 거 만큼 매 서비스를 이용할 때마다 깃허브 repo를 확인해야하니까 

검사하는 부분을 filter에 넣는 것은 어떨까 라는 생각이 들었다.

 

우선 늘 하던대로 JWT필터를 통해 인증을 마치고 그 다음에 레포를 검사하는 작업을 하는것이다.

 

@Component
class GitHubRepoVerificationFilter(
    private val memberValidator: MemberValidator
) : OncePerRequestFilter() {

    override fun doFilterInternal(
        request: HttpServletRequest,
        response: HttpServletResponse,
        filterChain: FilterChain
    ) {
        ...

            if (principal is UserDetails) {
                val username = principal.username
                memberValidator.isExistRepo(username)
            }
        }
        filterChain.doFilter(request, response)
    }
}

위의 코드가 바로 깃허브 repo를 검사하는 부분이다.

 

Github repo를 검사하는 filter 클래스를 하나 만든 후 인증된 객체를 갖고와서 그 객체의 repo가 있는지 없는지를 검사하는 것이다.

그리고 만약 repo가 없다면 에러가 발생하고 만약 정상적으로 레포가 존재한다면 다음 filter를 진행하는 로직으로 구현을 해두었다.

 

이렇게 만든 filter는 security에 등록을 해두어서 JWT토큰을 인증하는 방식처럼 자동으로 검사를 하게끔 해두었다.

 

그렇게 하고 바로 테스트를 진행하였고, 결과는 성공적이었다..!!

filter에서 검증

물론 매번 쿼리가 나간다는 단점은 있지만 우리 서비스의 핵심이라 뺼 수 없는 부분이라고 생각한다.

(다른 방법이 있다면 언제든지 댓글로 달아주시면 감사합니다!)

'Project > TDD' 카테고리의 다른 글

[Refactor] - TDD 서비스 코드를 간결하게 해보자,,!  (0) 2024.07.24