Интеграции
23 Mar

Как интегрироваться с сайтом без API: обход авторизации и парсинг админки

Image description

Многие разработчики сталкиваются с трудностями при интеграции со сторонними сервисами, особенно когда речь идет о доступе в закрытые части сайта — админки.

Предположим, вам нужно автоматизировать процесс закупки трафика через рекламную сеть. Для этого необходимо выполнить несколько шагов:

  1. Создать рекламную кампанию
  2. Подождать пока кампания пройдет модерацию
  3. Добавить в кампанию площадки с которых мы хотим закупить трафик
  4. Запустить кампанию

На первый взгляд, эти действия могут показаться простыми и не слишком трудоемкими. Однако, их сложность заключается в том, что они защищены авторизацией. То есть, просто отправить запрос для выполнения этих действий не получится — вы столкнетесь с ошибками 401 или 403. Чтобы избежать этого, нужно добавлять в запрос авторизационные данные, такие как куки, токены, API-ключи и другие.

Если у сайта есть API, то интеграция через него — это наилучший и «белый» способ взаимодействия. Но что делать, если API нет или оно сильно ограничено? В таких случаях приходится искать более экзотические способы интеграции.

Сохранение токенов авторизации

Чтобы выполнить запрос в закрытую часть сайта, выполните следующие шаги:

  1. Авторизуйтесь вручную на сайте через браузер.
  2. Во время авторизации или запроса в админке используйте консоль разработчика для захвата токена или куки и сохраните их.
  3. Используйте этот токен для выполнения последующих запросов к сайту.

Запрос без токена
Запрос на получение списка кампаний без авторизационных данных - 403 ошибка.

Получение токена
Получение токена во время ручной авторизации в рекламной сети clickadu

Запрос с токеном
Запрос на получение списка кампаний c авторизационными данными - 200 статус.

При добавлении токена в запрос мы получаем успешный ответ и список кампаний. Однако важно помнить об ограничениях: срок действия токена. Если он действует долго, то проблем не возникнет. В некоторых случаях токен можно обновить через специальный роут (зависит от сервиса). Также есть токены, которые действуют только при открытой вкладке браузера. Для точной информации об истечении срока действия можно проверить поле expire, если оно присутствует.

Автоматическая авторизация

В этом разделе мы рассмотрим автоматическое получение токенов и куки, однако основной проблемой является защита от спам-ботов, которая часто используется на сайтах — капча. Одной из самых популярных капч является reCaptcha от Google.

Если просто отправить запрос на авторизацию, то, скорее всего, вы столкнетесь с капчей. Например, при попытке авторизоваться в рекламной сети Clickaine:

Запрос на авторизацию без капчи

Как видно, на запрос приходит ошибка, требующая передачи токена капчи. Этот токен можно получить только если решить капчу, что в большинстве случаев требует участия человека.

Для решения капчи существуют платные сервисы, такие как ruCaptcha, которые позволяют обрабатывать капчу автоматически. Для работы с этим сервисом необходимо отправить site-key — публичный ключ сайта, на котором размещена капча, а также ссылку на страницу с капчей. Получив ответ, вы получите токен, который можно использовать для авторизации и последующих запросов.

Рассмотрим конкретные шаги, которые необходимо выполнить что бы решить капчу в рекламной сети Clickaine с помощью сервиса ruCaptcha.

Шаг 1: Найти параметры капчи

Для начала необходимо найти параметры капчи на странице авторизации. Для этого:

  1. Зайдите на страницу авторизации.
  2. Откройте консоль разработчика.
  3. Введите скрипт для поиска параметров капчи.
function findRecaptchaClients() {
  // eslint-disable-next-line camelcase
  if (typeof (___grecaptcha_cfg) !== 'undefined') {
    // eslint-disable-next-line camelcase, no-undef
    return Object.entries(___grecaptcha_cfg.clients).map(([cid, client]) => {
      const data = { id: cid, version: cid >= 10000 ? 'V3' : 'V2' };
      const objects = Object.entries(client).filter(([_, value]) => value && typeof value === 'object');

      objects.forEach(([toplevelKey, toplevel]) => {
        const found = Object.entries(toplevel).find(([_, value]) => (
          value && typeof value === 'object' && 'sitekey' in value && 'size' in value
        ));
        if (found) {
          const [sublevelKey, sublevel] = found;

          data.sitekey = sublevel.sitekey;
          const callbackKey = data.version === 'V2' ? 'callback' : 'promise-callback';
          const callback = sublevel[callbackKey];
          if (!callback) {
            data.callback = null;
            data.function = null;
          } else {
            data.function = callback;
            const keys = [cid, toplevelKey, sublevelKey, callbackKey].map((key) => `['${key}']`).join('');
            data.callback = `___grecaptcha_cfg.clients${keys}`;
          }
        }
      });
      return data;
    });
  }
  return [];
} 

Получение параметров капчи

Из примера видно, что для нашей капчи site-key: 6LfqyjcUAAAAAPKxO-VinwFYWGDzxpjGJtlHCjVT и версия капчи 2.

Шаг 2: Отправляем запрос на решение капчи

После того как мы получили site-key, отправляем POST-запрос на решение капчи через сервис ruCaptcha. Для этого нужно отправить запрос на адрес https://api.rucaptcha.com/createTask с параметрами в формате JSON::

  • clientKey — API-ключ от сервиса ruCaptcha.
  • task — объект задачи на решение капчи:
    • type — тип капчи, в нашем случае RecaptchaV2TaskProxyless.
    • websiteURL — ссылка на страницу с капчей.
    • websiteKey — публичный ключ капчи.

Например на такой запрос:

curl --location 'https://api.rucaptcha.com/createTask' \
--header 'Content-Type: application/json' \
--data '{
    "clientKey" : "c077a53840be768ae4a1cfef5c431461",
    "task" : {
        "type": "RecaptchaV2TaskProxyless",
        "websiteURL": "https://clickaine.com/login",
        "websiteKey": "6LfqyjcUAAAAAPKxO-VinwFYWGDzxpjGJtlHCjVT"
    }
}'

Получим такой ответ:

{
    "errorId": 0,
    "taskId": 53576589874
}

Итак мы успешно отправили запрос на решение капчи в сервис ruCaptcha

Шаг 3: Получаем токен для авторизации

После того как мы отправили запрос на решение капчи, необходимо отправить запрос на получение токена. Для этого мы выполняем POST-запрос на адрес https://api.rucaptcha.com/getTaskResult с параметрами в формате JSON:

  • clientKey - API-ключ от сервиса ruCaptcha.
  • taskId - идентификатор задачи, который мы получили в ответе на запрос в шаге 2.

Если капча решена, вы получите ответ с токеном. Если капча не решена, повторяйте запрос, пока не получите токен.

Например, сделаем запрос на получение ответа с токеном:

curl --location 'https://api.rucaptcha.com/getTaskResult' \
--header 'Content-Type: application/json' \
--data '{
    "clientKey": "c077a53840be768ae4a1cfef5c431461",
    "taskId" : "53576589874"
}'

И получим такой ответ:

{
    "errorId": 0,
    "status": "ready",
    "solution": {
        "gRecaptchaResponse": "03AFcWeA6hEdGZwIgaw1wkYhaG0GFow6tVM7sCOmBBw_OAycPZf-ot9n1z8VcMbF9-lcdiAb44mJNZEWsP6JaXI2CiM4DJQ9DhiyRY5A8TfaKjxd4cpccB-WvsZwZQ8qZpnhx_6vz6dKyTp_3TVHlC1kN-nkHBB8E_BE00eFGG2SvL28JiN2DU-7vhvT8Rix3F3tHf8og0E0LVAO__jtSoXBzY_1EkZ1FSVqmqhBB0ylG0u6TecTw6uSTTlg3zotFIyCrg88cvZl4FRS939p_XEczYpTjBE98GgCohea99QqusIeI41lykMIIzAVR08usYVsakGL5nEpE7XRq5Il2Pj3XbGVbfiHu_ceAL6R7HWpvreiLtpQivFtpUvJD-QAbzRfvD8-mDdVaQbB3wmNer9fdccvNszCLUty3cNEHmH2sNpjXwOiY9ORz6wDJxl0yGtR7NtxC3CKM_cC1G-wEHyvHzaAj85dh46-5ob1YjaDHgpRnwe-o-rXsKKc4oFG2nFp8UOK1FabaJWVE5Z5OgJY9uJPb-H69m_QHDe_Vn6WgXj-R4uW7PbxtCByvbh6soZho8_SzMxdIQrbfk8c0vZu3Mbyq2VxnG1JjgL0z1PDplMZ2fpfcEdUy8AfbjDH-Y-pQxesoN_mQnMvsYzWpSHsecP3eBgbah-V2ozK6AmEMKqVrM26yRmV-wg0heNosHYsLrdN7CCvTu69rBguwyLUFrwmH1F6AFm8Fq4KH06RnfCDWusFFYdJIr01uezGBlrT9zH7iRFuwiIrUZhN7UmoJkzR86tan8rt8SpWzepUdYiYAPr-lyK8n96lLNJFchD_viEA9eT_p5E1OHyLs5D6vp6MqSwG40PoH_j1oIdOnF28SLvcoXWfo3rmYoV0JJxRT41SNyrqyBFKvbZQZmXq5ZjhrOO31y01MSC7bbiVpoTBQum5Gi3YK1nds1ILWIecNSNocGQ3TBP9jsxJXX_9ilpgMGbundTCMixSaGUAsJN7j1UQOSlhWcszLgTXs8-hiwxDNB43UUhlvq96LZH5AWwLvfMS5uaABCO81NW9IXyCMT5iHJ6qM",
        "token": "03AFcWeA6hEdGZwIgaw1wkYhaG0GFow6tVM7sCOmBBw_OAycPZf-ot9n1z8VcMbF9-lcdiAb44mJNZEWsP6JaXI2CiM4DJQ9DhiyRY5A8TfaKjxd4cpccB-WvsZwZQ8qZpnhx_6vz6dKyTp_3TVHlC1kN-nkHBB8E_BE00eFGG2SvL28JiN2DU-7vhvT8Rix3F3tHf8og0E0LVAO__jtSoXBzY_1EkZ1FSVqmqhBB0ylG0u6TecTw6uSTTlg3zotFIyCrg88cvZl4FRS939p_XEczYpTjBE98GgCohea99QqusIeI41lykMIIzAVR08usYVsakGL5nEpE7XRq5Il2Pj3XbGVbfiHu_ceAL6R7HWpvreiLtpQivFtpUvJD-QAbzRfvD8-mDdVaQbB3wmNer9fdccvNszCLUty3cNEHmH2sNpjXwOiY9ORz6wDJxl0yGtR7NtxC3CKM_cC1G-wEHyvHzaAj85dh46-5ob1YjaDHgpRnwe-o-rXsKKc4oFG2nFp8UOK1FabaJWVE5Z5OgJY9uJPb-H69m_QHDe_Vn6WgXj-R4uW7PbxtCByvbh6soZho8_SzMxdIQrbfk8c0vZu3Mbyq2VxnG1JjgL0z1PDplMZ2fpfcEdUy8AfbjDH-Y-pQxesoN_mQnMvsYzWpSHsecP3eBgbah-V2ozK6AmEMKqVrM26yRmV-wg0heNosHYsLrdN7CCvTu69rBguwyLUFrwmH1F6AFm8Fq4KH06RnfCDWusFFYdJIr01uezGBlrT9zH7iRFuwiIrUZhN7UmoJkzR86tan8rt8SpWzepUdYiYAPr-lyK8n96lLNJFchD_viEA9eT_p5E1OHyLs5D6vp6MqSwG40PoH_j1oIdOnF28SLvcoXWfo3rmYoV0JJxRT41SNyrqyBFKvbZQZmXq5ZjhrOO31y01MSC7bbiVpoTBQum5Gi3YK1nds1ILWIecNSNocGQ3TBP9jsxJXX_9ilpgMGbundTCMixSaGUAsJN7j1UQOSlhWcszLgTXs8-hiwxDNB43UUhlvq96LZH5AWwLvfMS5uaABCO81NW9IXyCMT5iHJ6qM",
        "cookies": {
            "empty": "true"
        }
    },
    "cost": "0.16",
    "ip": "31.129.22.64",
    "createTime": 1742923416,
    "endTime": 1742923486,
    "solveCount": 2
}

Капча упешно решена и мы получили токен.

Шаг 4: Проходим авторизацию на сайте

Теперь токен, полученный в шаге 2, необходимо передать в теле запроса на авторизацию к рекламной сети Clickaine.

Отправлдяем запрос:

curl --location 'https://clkapi.com/v1/auth/login' \
--header 'Content-Type: application/json' \
--header 'Cookie: clkcl=1' \
--data-raw '{
  "username": "5uu5@mail.ru",
  "password": "7wGKd)zV",
  "recaptchaResponse": "03AFcWeA6hEdGZwIgaw1wkYhaG0GFow6tVM7sCOmBBw_OAycPZf-ot9n1z8VcMbF9-lcdiAb44mJNZEWsP6JaXI2CiM4DJQ9DhiyRY5A8TfaKjxd4cpccB-WvsZwZQ8qZpnhx_6vz6dKyTp_3TVHlC1kN-nkHBB8E_BE00eFGG2SvL28JiN2DU-7vhvT8Rix3F3tHf8og0E0LVAO__jtSoXBzY_1EkZ1FSVqmqhBB0ylG0u6TecTw6uSTTlg3zotFIyCrg88cvZl4FRS939p_XEczYpTjBE98GgCohea99QqusIeI41lykMIIzAVR08usYVsakGL5nEpE7XRq5Il2Pj3XbGVbfiHu_ceAL6R7HWpvreiLtpQivFtpUvJD-QAbzRfvD8-mDdVaQbB3wmNer9fdccvNszCLUty3cNEHmH2sNpjXwOiY9ORz6wDJxl0yGtR7NtxC3CKM_cC1G-wEHyvHzaAj85dh46-5ob1YjaDHgpRnwe-o-rXsKKc4oFG2nFp8UOK1FabaJWVE5Z5OgJY9uJPb-H69m_QHDe_Vn6WgXj-R4uW7PbxtCByvbh6soZho8_SzMxdIQrbfk8c0vZu3Mbyq2VxnG1JjgL0z1PDplMZ2fpfcEdUy8AfbjDH-Y-pQxesoN_mQnMvsYzWpSHsecP3eBgbah-V2ozK6AmEMKqVrM26yRmV-wg0heNosHYsLrdN7CCvTu69rBguwyLUFrwmH1F6AFm8Fq4KH06RnfCDWusFFYdJIr01uezGBlrT9zH7iRFuwiIrUZhN7UmoJkzR86tan8rt8SpWzepUdYiYAPr-lyK8n96lLNJFchD_viEA9eT_p5E1OHyLs5D6vp6MqSwG40PoH_j1oIdOnF28SLvcoXWfo3rmYoV0JJxRT41SNyrqyBFKvbZQZmXq5ZjhrOO31y01MSC7bbiVpoTBQum5Gi3YK1nds1ILWIecNSNocGQ3TBP9jsxJXX_9ilpgMGbundTCMixSaGUAsJN7j1UQOSlhWcszLgTXs8-hiwxDNB43UUhlvq96LZH5AWwLvfMS5uaABCO81NW9IXyCMT5iHJ6qM"
}'

Получаем ответ:

{
    "token": "eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3NDM1Nzg0MzAsInVzZXJfaWQiOjE5NDAsInJvbGVzIjpbMl19.t9Lgk2C3BfRvEIxS_1bWbIJ3-UnebVifOTe1t-mfAFuSjxPxzBMrxvLJIHq4z1rXTC6kZNqttNT_pm9iJJFkWw",
    "userId": 1940
}

Мы успешно прошли авторизацию на сайте и получили токен, который можем использовать для последующих запросов.

Так же у сервиса ruCaptcha есть расширение для браузера Chrome, благодаря которому вы сможете увидеть, как решается капча.

Комментарии
Коммент.