Okhttp3 Network Intercepter | Application Intercepter

동키·2025년 4월 11일

안드로이드

목록 보기
7/14

네트워크 인터셉터와 애플리케이션 인터셉터

이전의 OkHttp3 개념 및 Intercepter와 Authenticator 에서 Interceptor와 Authenticator를 이용해 accesstoken , refreshtoken 을 이용한 인증 방법에 대해 공부했습니다.

해당 내용을 스터디 시간에 발표를 했고 스터디원 분이 질문을 주셨습니다.

Authenticator 가 다시 Request 를 반환하는데 다시 네트워크 요청을 보내게 되어 Interceptor 에서 다시 헤더에 토큰을 추가할 텐데 이쪽에서 헤더를 다시 붙이는 이유가 있나요?

저도 오래되어 기억이 잘 나지 않지만 해당 도식화 순서가 맞는지??”

   override fun authenticate(route: Route?, response: Response): Request? {
        // 무한 루프 방지
        if (responseCount(response) >= 2) return null
        return runBlocking {
            runCatching {
                val refreshToken = tokenManager.getRefreshToken() ?: throw IllegalStateException("Refresh token is null")

                val tokenResponse = authService.refreshToken(refreshToken)
                if (tokenResponse.code != 200 && tokenResponse.data == null) {
                    throw IllegalStateException("refreshtokenRequest 발급 실패")
                }

                val tokenData = tokenResponse.data
                    ?: throw IllegalStateException("Token data is null")

                tokenManager.saveTokens(tokenData.accessToken, tokenData.refreshToken)

                response.request.newBuilder()
                    .header("Authorization", "Bearer ${tokenData.accessToken}")
                    .build()
            }.getOrElse {
                tokenManager.clear()
                null
            }
        }
    }
    
    OkHttpClient.Builder()
            .addInterceptor(loggingInterceptor)
            .addInterceptor(interceptor)
            .authenticator(authenticator)
            .build()

저 또한 그렇게 알고 있었지만 interceptor에 로그를 찍어봤지만 authenticate 가 호출된 후 기대했던 예상과는 달리 interceptor 에 대한 로그는 찍히지 않았습니다.

문제

  • authenticate 호출 → 재요청 → interceptor 의 로그가 찍혀야 하는데 안찍힘
  • authenticate 에 헤더에 새 토큰을 집어넣는 코드를 지우니 401 에러를 그대로 가져옴

해결과정

답은 역시…공식 문서에 있었습니다

인터셉터는 애플리케이션 인터셉터네트워크 인터셉터 로 분류됩니다.

우선 간단하게 말하면 애플리케이션 인터셉터 클라이언트가 최초 요청을 보낼 때 한 번 호출됩니다.

네트워크 인터셉터 는 실제 네트워크로 요청이 전송되기 직전과 응답이 도착한 직후마다 호출됩니다.

아 이러니… 내가 작성한 인터셉터에 로그가 안찍히지.. 했습니다.

위에서 제가 작성한 .addInterceptor(interceptor) 는 애플리케이션 인터셉터였기 때문입니다.

두 인터셉터에 대해서 알아보겠습니다.

그렇다면 Authenticator 는 누구에게 401을 받고 누구에게 request를 다시 보내는 걸가요?

자세하기 알아보기 전에 두 인터셉터의 차

네트워크 인터셉터

  • 보안 검사, 캐시 무효화, 압축 조작, 인증 후 재요청 등 “실제 네트워크 요청” 직전에 쓰임
  • 서버로 나가는 최종 헤더 확인
  • 응답 압축 해제
  • 진짜 네트워크 요청”에 대한 마지막 가공 또는 확인 용도

Application Interceptor

  • 클라이언트가 최초 요청을 보낼 때 한 번 호출됩니다.
  • 요청, 응답을 앱 수준에서 가공
  • 캐시 응답에도 동작
  • 인증 재시도 시 재호출 ❌

사용 예시:

  • 모든 요청에 공통 헤더 추가 (Authorization 등)
  • Query 파라미터 추가
  • Logging
  • API Key 추가

Network Interceptor

  • 네트워크 계층에서 작동
  • 진짜 전송 직전에 요청을 가로채거나 응답을 수정
  • 인증 재시도 시 재호출 ✅
  • 압축 해제 등 실제 전송 직전 작업 가능

사용 예시:

  • 최종 헤더 검증
  • 토큰 교체, 압축 조작
  • 요청 시간 측정
  • Retry 대상 확인

🔍 차이점 비교 테이블

항목Application InterceptorNetwork Interceptor
위치앱 ↔️ OkHttpOkHttp ↔️ 서버
호출 시점최초 요청 1번만인증 재시도 시에도 호출
캐시 응답 작동 여부✅ 작동❌ 작동 안 함
재요청에 다시 호출되는가?
압축, 보안, 인증 확인❌ 불가✅ 가능
용도공통 헤더, 로그보안, 인증, 요청 감시

결론

서버에서 401 을 받게되면 Autenticator 가 실행되고 여기서 반환된 request 는 내부적으로 chain.proceed(request) 을 통해 인터셉터들을 타고 가서(네트워크 인터셉터가 있다면 탐) 다시 서버에 요청을 보내게 됨.

좀 더 깊이 알고싶어 내부적으로 어떻게 동작하는지 궁금하여 okhttp의 github 를 통해 내부적인 인터셉터들의 존재 유무를 알게되었고 다음 포스팅에 이에 대해 다뤄보도록 하겠습니다.

profile
오늘 하루도 화이팅

0개의 댓글