Интеграция для React Native

Как интегрировать Servicepipe Mobile SDK в React Native-приложение.

Особенности SDK

React Native SDK содержит нативные SDK для Android и iOS, а также модуль, через который JavaScript-код взаимодействует с ними.

После интеграции SDK будет обрабатывать запросы, которые проходят через стандартный сетевой стек React Native:

  • fetch;

  • XMLHttpRequest;

  • библиотеки, которые используют fetch или XMLHttpRequest.

Менять существующие вызовы fetch и XMLHttpRequest не нужно.

Если в приложении есть собственные нативные модули с отдельными OkHttpClient, URLSession или другими HTTP-клиентами, подключите Servicepipe SDK к ним отдельно.

SDK работает только на Android и iOS. React Native Web не поддерживается.

Для базовой работы SDK не требует dangerous/runtime-разрешений приложения.

Android-часть SDK добавляет в манифест разрешение ACCESS_NETWORK_STATE. Оно нужно для анализа активной сети. Пользователь не увидит системный запрос на это разрешение.

Функционал для определения реальной страны нахождения устройства может использовать доступ к геолокации. SDK сам его не запрашивает. Если у приложения нет этого доступа, SDK использует другие источники данных: на Android мобильную сеть и таймзону, на iOS — таймзону.

Требования

  • React Native 0.79–0.85 — интеграция протестирована с этими версиями;

  • Android 7.0+ (min API 24);

  • OkHttp 5.1.0;

  • Kotlin 2.2.0;

  • iOS 15+;

  • Xcode 26.5;

  • Swift 6.3.

Если в вашем проекте используются другие версии React Native, OkHttp, Kotlin, Xcode или Swift, проверьте интеграцию на тестовой сборке.

Состав поставки

В корне поставки вас ждут:

  • README.md — инструкция по интеграции SDK в формате Markdown;

  • README.pdf — та же инструкция в формате PDF;

  • examples — демо-приложения:

    • SPExample-0-79-2.zip — демо-приложение для React Native 0.79.2;

    • SPExample-0-81-6.zip — демо-приложение для React Native 0.81.6.

  • react-native-servicepipe — локальный React Native-модуль, который нужно добавить в проект. Состоит из:

    • package.json — содержит название и версию модуля, точку входа в TypeScript API и настройки React Native Codegen;

    • Servicepipe.podspec — описывает подключение iOS-части через CocoaPods: указывает нативные исходники и готовый фреймворк SPURLSessionFramework.xcframework, которые CocoaPods добавит в iOS-проект при выполнении pod install;

    • src — TypeScript API, который приложение вызывает из JavaScript или TypeScript;

    • android — Android-часть React Native-модуля;

    • ios — iOS-часть React Native-модуля.

Интеграция

1. Добавьте React Native-модуль в проект

Скопируйте каталог react-native-servicepipe из архива SDK в ваш проект. Например, поместите его в каталог modules:

your-project/
├── modules/
│   └── react-native-servicepipe/
├── android/
├── ios/
└── package.json

В корне проекта добавьте модуль как локальную зависимость:

yarn add file:modules/react-native-servicepipe

После этого модуль появится в зависимостях приложения. React Native autolinking найдёт его Android- и iOS-части.

2. Добавьте Android-библиотеки

В android/app/build.gradle добавьте зависимости на AAR-файлы, которые находятся внутри установленного модуля:

dependencies {
    implementation files(
        "../../modules/react-native-servicepipe/android/libs/servicepipe-core-1.1.0-release.aar"
    )
    implementation files(
        "../../modules/react-native-servicepipe/android/libs/servicepipe-okhttp-1.1.0-release.aar"
    )
}

Пути указаны для случая, когда модуль находится в каталоге modules в корне проекта. Если вы разместили его в другом месте, измените пути.

После этого выполните Gradle Sync.

В результате вы подключите следующие файлы:

  • servicepipe-core содержит основную логику SDK;

  • servicepipe-okhttp подключает основную логику SDK к OkHttp, который используется сетевым модулем React Native на Android.

3. Подключите SDK к сетевому модулю Android

В MainApplication инициализируйте SDK и зарегистрируйте Activity lifecycle callbacks. Они нужны, чтобы SDK мог показывать CAPTCHA поверх экранов приложения.

Затем передайте React Native OkHttp-клиент, в который добавлен SPInterceptor:

import com.facebook.react.modules.network.OkHttpClientFactory
import com.facebook.react.modules.network.OkHttpClientProvider
import com.facebook.react.modules.network.OkHttpClientProvider.getOkHttpClient

import okhttp3.OkHttpClient

import ru.servicepipe.core.SPService
import ru.servicepipe.okhttp.SPInterceptor

В методе onCreate добавьте:

override fun onCreate() {
    super.onCreate()

    SPService.init(this)

    registerActivityLifecycleCallbacks(
        SPService.getSPInstance().getActivityCallbacks()
    )

    OkHttpClientProvider.setOkHttpClientFactory(
        SPOkHttpClientFactory(getOkHttpClient())
    )

    // Остальная инициализация приложения
}

Создайте SPOkHttpClientFactory. Его можно разместить в том же файле:

class SPOkHttpClientFactory(
    private val defaultClient: OkHttpClient
) : OkHttpClientFactory {

    override fun createNewNetworkModuleClient(): OkHttpClient {
        return defaultClient.newBuilder()
            .addInterceptor(
                SPInterceptor(SPService.getSPInstance())
            )
            .followRedirects(false)
            .build()
    }
}

SPInterceptor — это интеграция Servicepipe SDK с HTTP-клиентом приложения. Он не меняет бизнес-логику приложения, но подключает к HTTP-запросам служебную логику Servicepipe:

  • добавляет к запросам служебные cookies Servicepipe;

  • считывает и сохраняет cookie из заголовков Set-Cookie, которые передала в ответе система защиты;

  • если система защиты выдала CAPTCHA или JS-челлендж, обрабатывает этот сценарий и отображает антибот-проверку внутри приложения;

  • SDK может определять страну устройства и локальные признаки VPN, а также передавать эти данные вашему приложению локально (приложение должно вызывать API SDK) или добавлять к запросу в виде HTTP-заголовков.

SPInterceptor должен быть последним interceptor среди тех, которые изменяют заголовки запроса.

followRedirects(false) отключает автоматическую обработку редиректов. Благодаря этому SDK может отличить обычный редирект от перехода на CAPTCHA или JS-челлендж.

Если приложение уже использует собственный OkHttpClientFactory, не заменяйте его. Добавьте SPInterceptor в существующий builder и сохраните остальные interceptor, timeout и настройки клиента.

Как и другие OkHttp interceptor, SPInterceptor может передать приложению IOException. Учитывайте это при обработке сетевых ошибок.

4. Подключите iOS-часть SDK

После добавления React Native-модуля выполните:

cd ios
pod install
cd ..

CocoaPods прочитает Servicepipe.podspec и автоматически:

  • добавит нативный модуль Servicepipe;

  • подключит SPURLSessionFramework.xcframework;

  • добавит обработчик запросов React Native;

  • подготовит Codegen для JavaScript API SDK.

Запросы через fetch, XMLHttpRequest и библиотеки на их основе будут автоматически проходить через Servicepipe SDK.

5. Настройте режим отображения антибот-проверок (опционально)

Этот этап необязательный. Если ничего не настраивать, проверка будет показана во всплывающем окне с настройками по умолчанию.

Также по вашему запросу можем кастомизировать CAPTCHA (настраивается на стороне Servicepipe):

  • установить другой тип CAPTCHA — по умолчанию используется вариант с поворотом изображения, но можем вместо него установить капчу с вводом символов либо с установкой галочки в чекбокс;

  • установить в капчу с поворотом изображения присланные вами картинки;

  • оформить страницу капчи в вашем корпоративном стиле.

Доступные режимы отображения проверок

  • fullScreen/FULLSCREEN — на весь экран

  • windowed/WINDOWED — в окне поверх приложения

Настройка для Android

По умолчанию CAPTCHA и JS-челлендж показываются в режиме WINDOWED с cornerRadius 48 dp.

Чтобы изменить настройки, передайте нужную конфигурацию при инициализации SDK в MainApplication.

Для проверок на весь экран:

import ru.servicepipe.core.CaptchaConfiguration

SPService.init(
    this,
    CaptchaConfiguration.FULLSCREEN
)

Этот вызов нужно использовать вместо SPService.init(this), а не вместе с ним.

Для проверок в окне с заданным радиусом скругления:

val cornerRadius = 24f

SPService.init(
    this,
    CaptchaConfiguration.WINDOWED.withCornerRadius(cornerRadius)
)

Этот вызов нужно использовать вместо SPService.init(this), а не вместе с ним.

Настройка для iOS

По умолчанию используется режим windowed со следующими параметрами:

  • width: 360

  • height: 640

  • cornerRadius: 48

  • backgroundColor: UIColor.black.withAlphaComponent(0.3)

Чтобы изменить режим, вызовите нативный API до первого защищаемого запроса. Например, в AppDelegate.swift:

import SPURLSessionFramework

SPURLSession.setCaptchaPresentationMode(
    captchaPresentationMode: .fullScreen
)

6. Настройте отслеживание состояния CAPTCHA (опционально)

Этот этап необязательный. Выполните его, если хотите, чтобы приложение получало два события:

  • пользователь начал проходить CAPTCHA,

  • пользователь успешно прошёл CAPTCHA.

Зарегистрируйте callback:

import {
    setCaptchaStatusCallback,
    type CaptchaStatus,
} from "react-native-servicepipe";

setCaptchaStatusCallback((status: CaptchaStatus) => {
    console.log(
        `status: ${status.status} | IP: ${status.ip} | requestId: ${status.requestId}`
    );
}).catch((error) => {
    console.warn("Failed to set CAPTCHA callback:", error);
});

SDK будет передавать объект:

interface CaptchaStatus {
    status: "inProgress" | "solved";
    ip: string;
    requestId: string;
}

inProgress означает, что CAPTCHA-проверка началась. solved означает, что пользователь успешно её прошёл.

Вызовите setCaptchaStatusCallback один раз при запуске JavaScript-части приложения. Если вызвать функцию повторно, новая подписка заменит предыдущую.

7. Настройте получение страны и VPN-признаков (опционально)

SDK может определить страну, где находится устройство, и локальные признаки VPN. Эти данные ваше приложение может получить через API SDK либо их можно передать на ваш сервер в HTTP-заголовках.

Получить данные в приложении

Эти вызовы возвращают данные в JavaScript- или TypeScript-код приложения.

Местоположение (страна) устройства

Для определения страны, где сейчас находится устройство, SDK может использовать три источника данных:

  • GPS — на Android и iOS;

  • данные мобильной сети — только на Android;

  • таймзону устройства — на Android и iOS.

SDK сможет использовать данные GPS, только если у приложения есть доступ к геолокации.

Если результаты по ним отличаются, SDK сам выберет самый надёжный. Например, если GPS показывает одну страну, а таймзона — другую, SDK отдаст страну, определённую по GPS, так как этот источник надёжнее таймзоны.

Чтобы получить страну устройства, вызовите:

import {
    getCountryCode,
    type CountryCodeInfo,
} from "react-native-servicepipe";

const country: CountryCodeInfo = getCountryCode();

SDK вернёт объект:

interface CountryCodeInfo {
    countryCode: string;
    source: "GPS" | "NETWORK" | "TIMEZONE";
}

Например:

{
    countryCode: "ru",
    source: "GPS"
}

countryCode содержит двухбуквенный код страны по стандарту ISO 3166-1 alpha-2. source показывает, по данным какого источника SDK определил страну.

Признаки VPN

Чтобы получить признаки VPN, вызовите:

import {
    getVpnSigns,
    type VpnSign,
} from "react-native-servicepipe";

const vpnSigns: VpnSign[] = getVpnSigns();

SDK вернёт массив найденных VPN-признаков. Каждый элемент содержит описание признака, его тип и уровень уверенности:

interface VpnSign {
    description: string;
    type: "DIRECT" | "INDIRECT";
    confidence: "LOW" | "MEDIUM" | "HIGH";
}

Значения полей:

  • description описывает найденный признак;

  • type показывает, прямой это признак VPN или косвенный;

  • confidence показывает уровень уверенности SDK в этом признаке.

Если SDK не нашёл признаков VPN, функция вернёт пустой массив.

В текущей версии SDK используются следующие признаки:

  • indirect_sign_1 — обнаружен интерфейс tun* / utun* с нестандартным MTU, то есть не 1500;

  • direct_sign_1 — обнаружен системный прокси;

  • direct_sign_2 (доступен только на Android) — VPN обнаружен по характеристикам активной сети, полученным через ConnectivityManager.getNetworkCapabilities(activeNetwork).

Передать данные на сервер

SDK может добавлять к запросам HTTP-заголовки с информацией о стране устройства и признаках VPN.

Чтобы включить эту механику, вызовите setSendVpnHeaders(true):

import { setSendVpnHeaders } from "react-native-servicepipe";

setSendVpnHeaders(true);

Функция setSendVpnHeaders(true) включает передачу и VPN-признаков, и страны устройства.

После этого SDK будет добавлять к защищаемым запросам заголовки:

x-cybert-mobile-country-code: ru
x-cybert-mobile-vpn-signs: direct_sign_1,indirect_sign_1

x-cybert-mobile-country-code передаёт двухбуквенный код страны по стандарту ISO 3166-1 alpha-2.

x-cybert-mobile-vpn-signs передаёт найденные признаки VPN:

  • indirect_sign_1 — обнаружен интерфейс tun* / utun* с нестандартным MTU, то есть не 1500;

  • direct_sign_1 — обнаружен системный прокси;

  • direct_sign_2 (доступен только на Android) — VPN обнаружен по характеристикам активной сети, полученным через ConnectivityManager.getNetworkCapabilities(activeNetwork).

Если признаков VPN нет, заголовка x-cybert-mobile-vpn-signs в запросе не будет.

Если захотите отключить добавление этих двух заголовков к запросам, вызовите:

setSendVpnHeaders(false);

8. Протестируйте интеграцию

Сначала проверьте, что приложение работает как раньше:

  1. Запустите приложение с подключённым SDK.

  2. Пройдите основные сценарии, где приложение обращается к API: например, авторизацию, загрузку данных, отправку формы или оформление заказа.

  3. Убедитесь, что запросы выполняются успешно, ответы API обрабатываются как раньше и пользовательские сценарии завершаются без ошибок.

  4. Если включили передачу информации о стране устройства или VPN:

    • напрямую приложению (через API SDK) — проверьте на тестовой сборке, что приложение получило нужные данные;

    • на сервер (в HTTP-заголовках) — сначала проверьте на тестовой сборке, что запросы содержат x-cybert-mobile-country-code, затем включите VPN и проверьте, что появился x-cybert-mobile-vpn-signs.

Затем проверьте, что SDK корректно обрабатывает CAPTCHA. Для этого выполните из приложения запрос к тестовому URL:

https://servicepipe.ru/F2xN8dM3sPqK6aZt

Если интеграция работает:

  • SDK покажет CAPTCHA в Android WebView или iOS WKWebView;

  • если вы настроили отслеживание состояния, при показе капчи callback получит статус inProgress, а после её успешного прохождения пользователем — solved;

  • после прохождения капчи тестовый URL вернёт HTTP 404;

  • при повторном запросе CAPTCHA не появится, потому что SDK сохранит разрешающую cookie.

Когда срок жизни cookie истечёт или пользователь переустановит приложение, тестовый URL снова покажет CAPTCHA.

Запуск демо-приложения

В архиве SDK в каталоге examples находятся демо-приложения для React Native 0.79.2 и 0.81.6. В них уже интегрирован Servicepipe SDK, а тестовый URL добавлен по умолчанию.

Чтобы запустить демо-приложение, распакуйте архив с нужной версией React Native. Затем в корне папки SPExample выполните:

yarn install

cd ios
pod install
cd ..

yarn start --reset-cache

После запуска Metro откройте приложение на нужной платформе:

yarn ios

или:

yarn android