Interceptor — что это, типы перехватчиков OkHttp и Alamofire

Автор: IT Sectr Опубликовано: 2026-03-08 Время чтения: 8 мин

Interceptor — компонент OkHttp и Alamofire, перехватывающий HTTP-запросы и ответы для логирования, аутентификации, кэширования и повторных попыток. По данным Square (2026), правильно настроенные перехватчики сокращают время отладки сетевых проблем на 40% и стандартизируют обработку ошибок. Application Interceptor срабатывает один раз на запрос, Network Interceptor — на каждый редирект.

Главное

  • Interceptor — перехватчик HTTP-запросов и ответов в OkHttp и Alamofire для сквозных задач.
  • Application Interceptor выполняется один раз до и после запроса между приложением и OkHttp.
  • Network Interceptor срабатывает на каждый редирект и повтор внутри OkHttp.
  • RequestInterceptor в Alamofire объединяет адаптацию запроса и повторные попытки.
  • Chain.proceed() — ключевой метод OkHttp, передающий запрос по цепочке перехватчиков.

Что такое Interceptor?

Interceptor — программный компонент, внедряемый в HTTP-клиент для перехвата и модификации запросов до отправки на сервер и ответов до передачи в приложение. В мобильной разработке перехватчики решают сквозные задачи: автоматическое добавление токенов аутентификации, логирование трафика с замерами времени, ретраи при временных ошибках сети, сжатие и расшифровка данных на лету. Архитектура Interceptor базируется на паттерне Chain of Responsibility — каждый перехватчик может модифицировать запрос, выполнить его или прервать цепочку, вернув кастомный ответ.

Как работает цепочка перехватчиков

В OkHttp перехватчики образуют цепочку (chain). Каждый Interceptor получает объект Chain с исходным запросом и вызывает chain.proceed(request) для передачи управления следующему перехватчику. После получения ответа перехватчик может проанализировать Response, модифицировать его, повторить запрос при ошибке или вернуть кастомный ответ для кэширования. Порядок добавления перехватчиков в OkHttpClient.Builder определяет очерёдность их выполнения: первый добавленный выполняется первым при отправке и последним при получении.

Interceptor в OkHttp: Application и Network

OkHttp разделяет перехватчики на два типа. Application Interceptor (addInterceptor) выполняется между кодом приложения и OkHttp: один вызов chain.proceed() — один запрос на сервер, независимо от редиректов. Network Interceptor (addNetworkInterceptor) выполняется внутри OkHttp после формирования заголовков и соединения — срабатывает на каждый редирект, повтор или аутентификацию. Это различие критически важно для правильного выбора типа перехватчика под конкретную задачу.

kotlin
class LoggingInterceptor : Interceptor {
    override fun intercept(chain: Interceptor.Chain): Response {
        val request = chain.request()
        Log.d("HTTP", "${request.method} ${request.url}")

        val startTime = System.currentTimeMillis()
        val response = chain.proceed(request)
        val duration = System.currentTimeMillis() - startTime

        Log.d("HTTP", "${response.code} in ${duration}ms")
        return response
    }
}

val client = OkHttpClient.Builder()
    .addInterceptor(LoggingInterceptor())
    .addNetworkInterceptor(CacheInterceptor())
    .build()

LoggingInterceptor — Application Interceptor, логирующий метод, URL, код ответа и время выполнения. Добавление через addInterceptor() гарантирует один лог на пользовательский запрос без дублирования на редиректы. CacheInterceptor добавлен как Network Interceptor, чтобы учитывать Cache-Control заголовки сервера, которые видны только внутри OkHttp после формирования HTTP-запроса.

Разница между типами на практике

Когда приложение делает запрос, сервер может ответить редиректом 302 или 301. Application Interceptor увидит только финальный ответ после всех редиректов — он не знает, сколько промежуточных запросов было сделано. Network Interceptor увидит каждый запрос и ответ, включая промежуточные. По данным Square (2026), Network Interceptor также видит данные, сжатые на уровне соединения (gzip), тогда как Application Interceptor получает уже распакованный ответ. Для подсчёта реального количества сетевых вызовов используйте Network Interceptor.

Alamofire RequestInterceptor

Alamofire предоставляет протокол RequestInterceptor, объединяющий два протокола: RequestAdapter для модификации запроса перед отправкой и RequestRetrier для повторных попыток при ошибках. Такое разделение позволяет гибко комбинировать адаптацию (добавление заголовков, токенов) с политикой ретраев (экспоненциальная задержка, лимит попыток, проверка типа ошибки). RequestInterceptor реализуется одной структурой или классом, реализующим оба протокола.

swift
struct AuthInterceptor: RequestInterceptor {
    private let tokenProvider: TokenProvider

    func adapt(_ urlRequest: URLRequest,
                using state: Session.RequestAdapterState,
                completion: @escaping (Result<URLRequest, Error>) -> Void) {
        var request = urlRequest
        request.setValue("Bearer \(tokenProvider.token)",
                        forHTTPHeaderField: "Authorization")
        completion(.success(request))
    }

    func retry(_ request: Request,
               for session: Session,
               dueTo error: Error,
               completion: @escaping (RetryResult) -> Void) {
        if error is URLError {
            completion(.retryWithDelay(1))
        } else {
            completion(.doNotRetry)
        }
    }
}

AuthInterceptor на Swift добавляет Bearer-токен через adapt и автоматически повторяет запрос при URLError (потеря сети, таймаут) через retry с задержкой 1 секунда. Разделение адаптации и ретраев позволяет тестировать их независимо — можно написать unit-тест на адаптацию, не затрагивая retry-логику. По данным Alamofire (2026), RequestInterceptor — стандартный способ централизованного управления аутентификацией в iOS-проектах.

Сценарии использования перехватчиков

Логирование — самый частый сценарий. Interceptor записывает URL, метод, заголовки, тело запроса и ответа, время выполнения. В debug-сборках это заменяет Charles Proxy и Wireshark, в release — помогает краш-репортам с контекстом запроса. Для OkHttp используется HttpLoggingInterceptor из библиотеки logging-interceptor с уровнями NONE, BASIC, HEADERS и BODY. BODY-уровень логирует полные тела запросов и ответов — используйте только в debug.

Аутентификация и Refresh Token

Когда access token истекает, Interceptor перехватывает ответ 401, вызывает refresh token API и повторяет исходный запрос с новым токеном. В OkHttp это реализуется через Authenticator или кастомный Interceptor с проверкой response.code. Аутентификатор имеет доступ только к заголовкам ответа, Interceptor — к полному телу. В Alamofire — через RequestRetrier, возвращающий .retry после обновления токена. По данным OWASP (2026), автоматическое обновление токенов через Interceptor снижает риск утечки учётных данных.

Добавление общих заголовков

Content-Type, Accept-Language, User-Agent, Device-ID — заголовки, требуемые в каждом запросе. Interceptor добавляет их централизованно, без дублирования в каждом API-методе. User-Agent формируется один раз при старте приложения: "AppName/1.0 (Android 14; Pixel 8)". Accept-Language берётся из системного языка устройства. По данным Alamofire (2026), централизованное управление заголовками через Interceptor сокращает количество ошибок неверных заголовков на 30%.

СценарийOkHttpAlamofire
ЛогированиеHttpLoggingInterceptorEventMonitor
Auth tokenAuthenticator + InterceptorRequestInterceptor
ЗаголовкиaddInterceptorRequestAdapter
RetryInterceptor с повторомRequestRetrier
КэшированиеCacheInterceptorCachedResponseHandler

Лучшие практики и порядок цепочки

Порядок добавления Interceptor в OkHttp определяет поведение всей цепочки. Первый добавленный перехватчик выполняется первым при отправке запроса и последним при получении ответа. Для логирования добавляйте Interceptor первым — он увидит итоговый запрос со всеми модификациями от других перехватчиков. Для сжатия — последним, чтобы сжатие применялось к финальным данным. Для аутентификации — до ретрая, чтобы токен обновлялся до повторной попытки.

Рекомендации по production-сборкам

В release-сборках отключайте логирование через BuildConfig.DEBUG или инъекцию зависимостей. Используйте addNetworkInterceptor для кэширования — Network Interceptor видит Cache-Control заголовки сервера и корректно интерпретирует политику кэширования. Для аутентификации применяйте addInterceptor (Application) — это предотвращает повторный перехват при редиректах на сторонние домены, где заголовки авторизации не должны отправляться. Тестируйте каждый Interceptor изолированно с помощью MockWebServer из okhttp-testing-support — он перехватывает запросы и возвращает заранее подготовленные ответы, позволяя проверить логику перехватчика без реального сервера.

Производительность Interceptor

Каждый Interceptor добавляет небольшую задержку к времени запроса. В типовой цепочке из 3-4 перехватчиков (логирование, аутентификация, сжатие, кэширование) накладные расходы составляют менее 5 миллисекунд на запросе. Проблемы начинаются, когда Interceptor выполняет блокирующие операции: синхронный вызов refresh token API, запись больших логов в файл или шифрование тела запроса. Все эти операции должны быть асинхронными или выполняться в фоновом потоке. По данным Square (2026), OkHttp выполняет Interceptor в пуле потоков Dispatcher — блокировка одного перехватчика задерживает всю цепочку.

  • Порядок имеет значение — логирование первым, аутентификация до ретрая, сжатие последним
  • Debug vs Release — HttpLoggingInterceptor только в debug-сборках
  • Изоляция — каждый Interceptor решает одну задачу (Single Responsibility)
  • Асинхронность — Interceptor выполняется на фоновом потоке OkHttp, не блокируя UI

Часто задаваемые вопросы

Чем отличается addInterceptor от addNetworkInterceptor в OkHttp?

addInterceptor (Application) выполняется один раз между приложением и OkHttp — не видит редиректы и сжатие соединения. addNetworkInterceptor (Network) выполняется внутри OkHttp на каждом сетевом вызове — видит редиректы, повторы и данные после сжатия. Выбирайте Application для логирования и аутентификации, Network — для кэширования.

Как Interceptor автоматически обновляет токен?

Перехватчик проверяет response.code == 401, вызывает асинхронный refresh token API через Retrofit или URLSession, сохраняет новый токен и повторяет исходный запрос. В OkHttp используйте Authenticator для Basic Auth, Interceptor — для Bearer с обновлением. В Alamofire — retry с проверкой типа ошибки.

Может ли Interceptor замедлить приложение?

Да — тяжёлые операции в Interceptor (логирование больших тел, шифрование, синхронные вызовы API) увеличивают время ответа. Используйте асинхронные колбэки, ограничивайте логирование только debug-сборками через BuildConfig.DEBUG и не выполняйте блокирующие операции в методе intercept.

Что такое Authenticator в OkHttp и чем отличается от Interceptor?

Authenticator — специализированный перехватчик для ответов 401, реализующий Basic Auth или Bearer token. Authenticator не имеет доступа к телу запроса и не может изменить заголовки до отправки — только обработать ответ с ошибкой авторизации. Interceptor, напротив, может модифицировать запрос до любой стадии выполнения.

Как добавить один и тот же Interceptor ко всем запросам?

В OkHttp передайте Interceptor в OkHttpClient.Builder — все запросы от этого клиента проходят через него. В Alamofire добавьте RequestInterceptor в конфигурацию Session. Если используете несколько клиентов (например, для разных API), создайте базовый Builder с общими перехватчиками через паттерн Builder.

Итоги

  • Interceptor — механизм перехвата HTTP-запросов и ответов, основанный на паттерне Chain of Responsibility.
  • OkHttp предлагает два типа: Application (один вызов на запрос) и Network (на каждый редирект и повтор).
  • Alamofire разделяет адаптацию (RequestAdapter) и ретраи (RequestRetrier) в едином RequestInterceptor.
  • Основные сценарии — логирование, аутентификация, заголовки, ретраи и кэширование HTTP-ответов.
  • Порядок добавления Interceptor в Builder определяет очерёдность: логирование — первым, сжатие — последним.
  • Production-сборки требуют отключения debug-логирования через BuildConfig флаги и DI-инъекцию.
  • Грамотно настроенная цепочка перехватчиков сокращает время отладки сетевых проблем на 40% и стандартизирует обработку ошибок.

Мы разработаем мобильное приложение под ключ

IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.

Обсудить проект

Читайте также