НейроАгент

PHP-прокси для 1С и Битрикс24 с OAuth

Полное руководство по созданию универсального PHP-прокси для интеграции 1С с API Битрикс24. Автоматическая OAuth авторизация, обработка запросов и возврат ответов.

Вопрос

Как реализовать PHP-прокси для перенаправления запросов от 1С к API Битрикс24 с автоматической OAuth авторизацией?

Нужно отправить данные из 1С в Битрикс24, но штатный коннектор не подходит. Некоторые методы API (например, crm.deal.add) работают через простой cURL запрос с вебхуком, но другие (например, catalog.product.add) требуют OAuth авторизации от администратора.

Как создать PHP-скрипт, который будет:

  • Принимать POST запросы от 1С
  • Автоматически выполнять OAuth авторизацию в Битрикс24
  • Перенаправлять запросы к любым методам API
  • Возвращать ответ обратно в 1С

Скрипт должен быть универсальным и не зависеть от конкретных методов API.

НейроАгент

Для реализации PHP-прокси перенаправления запросов от 1С к API Битрикс24 с автоматической OAuth авторизацией создайте универсальный скрипт, который обрабатывает входящие запросы, выполняет двухэтапную OAuth аутентификацию (получение authorization code и обмен на access token) и перенаправляет запросы к любым методам API через полученные токены.

Содержание


Основные принципы работы прокси

PHP-прокси для Bitrix24 API должен работать как промежуточное звено между 1С и Bitrix24, решая проблему несовместимости стандартного коннектора с OAuth-защищенными методами.

Ключевые требования к прокси:

  • Принимать POST-запросы от 1С через HTTP
  • Автоматически управлять сессиями OAuth
  • Поддерживать все методы API без жесткой привязки
  • Обрабатывать ошибки и возвращать корректные ответы
  • Хранить учетные данные безопасно

Основная архитектура предусматривает три основных компонента:

  1. Приемник запросов - обработчик входящих данных от 1С
  2. OAuth менеджер - управление токенами авторизации
  3. API ретранслятор - перенаправление запросов к Bitrix24

Настройка OAuth 2.0 авторизации

Для работы с Bitrix24 необходимо зарегистрировать приложение и получить необходимые параметры авторизации.

Получение учетных данных Bitrix24

  1. Зайдите в ваш портал Bitrix24
  2. Перейдите в раздел “Разработчикам” → “Приложения” → “Создать приложение”
  3. Укажите тип приложения “Веб-сервис”
  4. Настройте параметры:
    • Client ID - идентификатор приложения
    • Client Secret - секретный ключ
    • Redirect URI - URL вашего прокси-скрипта
    • Scope - необходимые права доступа (например, crm,catalog)

Базовый OAuth flow для Bitrix24

Процесс авторизации включает два основных шага:

php
// Шаг 1: Получение authorization code
$auth_url = "https://{domain}.bitrix24.com/oauth/authorize/" .
    "?client_id=" . urlencode($client_id) .
    "&response_type=code" .
    "&redirect_uri=" . urlencode($redirect_uri);

// Шаг 2: Обмен authorization code на access token
$token_url = "https://{domain}.bitrix24.com/oauth/token/" .
    "?client_id=" . urlencode($client_id) .
    "&client_secret=" . urlencode($client_secret) .
    "&grant_type=authorization_code" .
    "&redirect_uri=" . urlencode($redirect_uri) .
    "&code=" . urlencode($code);

Как указано в официальной документации Bitrix24, после успешной авторизации возвращаются два важных параметра: access_token для доступа к API и refresh_token для продления сессии.


Структура PHP-прокси скрипта

Основной скрипт должен быть организован по модульному принципу для обеспечения гибкости и расширяемости.

Файлы проекта

/bitrix24-proxy/
├── config.php          # Конфигурация
├── oauth_manager.php   # Управление OAuth
├── api_client.php      # Клиент API
├── proxy_handler.php   # Основной обработчик
├── token_storage.php   # Хранилище токенов
└── index.php           # Точка входа

Конфигурационный файл

php
<?php
// config.php
return [
    'bitrix24' => [
        'client_id' => 'your_client_id',
        'client_secret' => 'your_client_secret',
        'redirect_uri' => 'https://your-domain.com/bitrix24-proxy/index.php',
        'scope' => 'crm,catalog,document'
    ],
    'storage' => [
        'type' => 'file', // file, database, session
        'path' => __DIR__ . '/tokens/'
    ],
    'security' => [
        'allowed_ips' => ['1c-server-ip', 'localhost'],
        'auth_token' => 'your-secret-auth-token'
    ]
];

Реализация автоматического обновления токенов

Токены доступа Bitrix24 имеют ограниченное время жизни, поэтому необходимо реализовать их автоматическое обновление.

Хранение токенов

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

php
<?php
// token_storage.php
class TokenStorage {
    private $config;
    
    public function __construct($config) {
        $this->config = $config;
    }
    
    public function saveToken($domain, $token_data) {
        $file = $this->config['storage']['path'] . md5($domain) . '.json';
        file_put_contents($file, json_encode($token_data));
    }
    
    public function getToken($domain) {
        $file = $this->config['storage']['path'] . md5($domain) . '.json';
        if (file_exists($file)) {
            return json_decode(file_get_contents($file), true);
        }
        return null;
    }
}

Автоматическое обновление токенов

Как указано в документации по автоматическому обновлению OAuth, refresh_token позволяет получать новые access_token без участия пользователя.

php
<?php
// oauth_manager.php
class OAuthManager {
    private $config;
    private $storage;
    
    public function __construct($config, $storage) {
        $this->config = $config;
        $this->storage = $storage;
    }
    
    public function getAccessToken($domain) {
        $token_data = $this->storage->getToken($domain);
        
        if (!$token_data) {
            return $this->authorize($domain);
        }
        
        // Проверяем, не истек ли токен
        if (time() >= $token_data['expires_at']) {
            return $this->refreshToken($domain, $token_data);
        }
        
        return $token_data['access_token'];
    }
    
    private function refreshToken($domain, $token_data) {
        $refresh_url = "https://{$domain}.bitrix24.com/oauth/token/" .
            "?client_id=" . urlencode($this->config['bitrix24']['client_id']) .
            "&client_secret=" . urlencode($this->config['bitrix24']['client_secret']) .
            "&grant_type=refresh_token" .
            "&refresh_token=" . urlencode($token_data['refresh_token']);
        
        $response = $this->makeHttpRequest($refresh_url, [], 'GET');
        $new_token = json_decode($response, true);
        
        if (isset($new_token['access_token'])) {
            $new_token['expires_at'] = time() + $new_token['expires_in'];
            $this->storage->saveToken($domain, $new_token);
            return $new_token['access_token'];
        }
        
        throw new Exception("Не удалось обновить токен");
    }
}

Обработка запросов от 1С

Основной обработчик должен принимать запросы от 1С, аутентифицировать их и перенаправлять в Bitrix24.

Точка входа (index.php)

php
<?php
// index.php
require_once 'config.php';
require_once 'oauth_manager.php';
require_once 'api_client.php';
require_once 'proxy_handler.php';

header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST, GET, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type');

$handler = new ProxyHandler($config);
echo $handler->handleRequest();

Основной обработчик запросов

php
<?php
// proxy_handler.php
class ProxyHandler {
    private $config;
    private $oauth_manager;
    private $api_client;
    
    public function __construct($config) {
        $this->config = $config;
        $storage = new TokenStorage($config);
        $this->oauth_manager = new OAuthManager($config, $storage);
        $this->api_client = new ApiClient();
    }
    
    public function handleRequest() {
        // Проверка метода запроса
        if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
            http_response_code(200);
            exit;
        }
        
        if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
            return $this->errorResponse('Метод не поддерживается', 405);
        }
        
        // Проверка аутентификации от 1С
        if (!$this->verify1CAuthentication()) {
            return $this->errorResponse('Ошибка аутентификации', 401);
        }
        
        // Получение данных из запроса
        $input = file_get_contents('php://input');
        $data = json_decode($input, true);
        
        if (!$data || !isset($data['domain']) || !isset($data['method'])) {
            return $this->errorResponse('Неверный формат запроса', 400);
        }
        
        try {
            // Получаем токен доступа
            $access_token = $this->oauth_manager->getAccessToken($data['domain']);
            
            // Выполняем запрос к Bitrix24 API
            $response = $this->api_client->callBitrix24API(
                $data['domain'],
                $access_token,
                $data['method'],
                $data['params'] ?? []
            );
            
            return $this->successResponse($response);
            
        } catch (Exception $e) {
            return $this->errorResponse($e->getMessage(), 500);
        }
    }
    
    private function verify1CAuthentication() {
        // Простая проверка - можно усилить
        $auth_header = $_SERVER['HTTP_AUTHORIZATION'] ?? '';
        return $auth_header === 'Bearer ' . $this->config['security']['auth_token'];
    }
    
    private function successResponse($data) {
        return json_encode([
            'success' => true,
            'data' => $data
        ]);
    }
    
    private function errorResponse($message, $code = 400) {
        http_response_code($code);
        return json_encode([
            'success' => false,
            'error' => $message,
            'code' => $code
        ]);
    }
}

Возврат ответов в 1С

Для корректной работы с 1С необходимо обеспечить форматирование ответов в соответствии с требованиями системы.

Форматирование ответов

php
<?php
// api_client.php
class ApiClient {
    public function callBitrix24API($domain, $access_token, $method, $params = []) {
        // Подготовка URL запроса
        $api_url = "https://{$domain}.bitrix24.com/rest/{$method}";
        
        // Добавление access token в параметры
        $params['auth'] = $access_token;
        
        // Формирование запроса
        $ch = curl_init();
        
        curl_setopt_array($ch, [
            CURLOPT_URL => $api_url,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_POST => true,
            CURLOPT_POSTFIELDS => http_build_query($params),
            CURLOPT_HTTPHEADER => [
                'Content-Type: application/x-www-form-urlencoded'
            ],
            CURLOPT_TIMEOUT => 30,
            CURLOPT_CONNECTTIMEOUT => 10
        ]);
        
        $response = curl_exec($ch);
        $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $error = curl_error($ch);
        curl_close($ch);
        
        if ($error) {
            throw new Exception("cURL ошибка: " . $error);
        }
        
        $result = json_decode($response, true);
        
        // Обработка ошибок от Bitrix24
        if (isset($result['error'])) {
            throw new Exception("Bitrix24 API ошибка: " . $result['error_description']);
        }
        
        return $result;
    }
}

Пример полного кода

Вот полный пример универсального PHP-прокси для работы с API Bitrix24:

php
<?php
// bitrix24_proxy.php - единый файл реализации

// Конфигурация
$config = [
    'bitrix24' => [
        'client_id' => 'your_client_id_here',
        'client_secret' => 'your_client_secret_here',
        'redirect_uri' => 'https://your-domain.com/bitrix24_proxy.php',
        'scope' => 'crm,catalog,document,telephony'
    ],
    'security' => [
        'auth_token' => 'your-secret-auth-token-for-1c'
    ]
];

// Класс для работы с токенами
class TokenStorage {
    private $config;
    
    public function __construct($config) {
        $this->config = $config;
        if (!file_exists($this->config['storage']['path'])) {
            mkdir($this->config['storage']['path'], 0700, true);
        }
    }
    
    public function saveToken($domain, $token_data) {
        $file = $this->config['storage']['path'] . md5($domain) . '.json';
        file_put_contents($file, json_encode($token_data));
    }
    
    public function getToken($domain) {
        $file = $this->config['storage']['path'] . md5($domain) . '.json';
        if (file_exists($file)) {
            $data = json_decode(file_get_contents($file), true);
            if (isset($data['expires_at']) && time() < $data['expires_at']) {
                return $data;
            }
        }
        return null;
    }
}

// Класс для OAuth управления
class OAuthManager {
    private $config;
    private $storage;
    
    public function __construct($config, $storage) {
        $this->config = $config;
        $this->storage = $storage;
    }
    
    public function getAccessToken($domain) {
        $token_data = $this->storage->getToken($domain);
        
        if (!$token_data) {
            return $this->authorize($domain);
        }
        
        return $token_data['access_token'];
    }
    
    private function refreshToken($domain, $token_data) {
        $refresh_url = "https://{$domain}.bitrix24.com/oauth/token/" .
            "?client_id=" . urlencode($this->config['bitrix24']['client_id']) .
            "&client_secret=" . urlencode($this->config['bitrix24']['client_secret']) .
            "&grant_type=refresh_token" .
            "&refresh_token=" . urlencode($token_data['refresh_token']);
        
        $response = $this->makeHttpRequest($refresh_url, [], 'GET');
        $new_token = json_decode($response, true);
        
        if (isset($new_token['access_token'])) {
            $new_token['expires_at'] = time() + $new_token['expires_in'];
            $this->storage->saveToken($domain, $new_token);
            return $new_token['access_token'];
        }
        
        throw new Exception("Не удалось обновить токен");
    }
    
    private function makeHttpRequest($url, $data = [], $method = 'POST') {
        $ch = curl_init();
        
        if ($method === 'POST') {
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
        } else {
            curl_setopt($ch, CURLOPT_HTTPGET, true);
        }
        
        curl_setopt_array($ch, [
            CURLOPT_URL => $url,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_TIMEOUT => 30,
            CURLOPT_HTTPHEADER => [
                'Content-Type: application/x-www-form-urlencoded'
            ]
        ]);
        
        $response = curl_exec($ch);
        curl_close($ch);
        
        return $response;
    }
}

// Основной обработчик
header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST, GET, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, Authorization');

if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    http_response_code(200);
    exit;
}

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    http_response_code(405);
    echo json_encode(['success' => false, 'error' => 'Метод не поддерживается']);
    exit;
}

// Проверка аутентификации
$auth_header = $_SERVER['HTTP_AUTHORIZATION'] ?? '';
if ($auth_header !== 'Bearer ' . $config['security']['auth_token']) {
    http_response_code(401);
    echo json_encode(['success' => false, 'error' => 'Ошибка аутентификации']);
    exit;
}

// Получение данных запроса
$input = file_get_contents('php://input');
$data = json_decode($input, true);

if (!$data || !isset($data['domain']) || !isset($data['method'])) {
    http_response_code(400);
    echo json_encode(['success' => false, 'error' => 'Неверный формат запроса']);
    exit;
}

try {
    // Инициализация компонентов
    $storage = new TokenStorage(array_merge($config, ['storage' => ['path' => __DIR__ . '/tokens/']]));
    $oauth_manager = new OAuthManager($config, $storage);
    
    // Получение токена доступа
    $access_token = $oauth_manager->getAccessToken($data['domain']);
    
    // Формирование запроса к Bitrix24 API
    $api_url = "https://{$data['domain']}.bitrix24.com/rest/{$data['method']}";
    $params = isset($data['params']) ? $data['params'] : [];
    $params['auth'] = $access_token;
    
    // Выполнение запроса
    $ch = curl_init();
    curl_setopt_array($ch, [
        CURLOPT_URL => $api_url,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POST => true,
        CURLOPT_POSTFIELDS => http_build_query($params),
        CURLOPT_TIMEOUT => 30,
        CURLOPT_HTTPHEADER => [
            'Content-Type: application/x-www-form-urlencoded'
        ]
    ]);
    
    $response = curl_exec($ch);
    $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    
    $result = json_decode($response, true);
    
    // Обработка ответа
    if ($http_code === 200 && !isset($result['error'])) {
        echo json_encode(['success' => true, 'data' => $result]);
    } else {
        throw new Exception(isset($result['error_description']) ? 
            $result['error_description'] : 'Ошибка API запроса');
    }
    
} catch (Exception $e) {
    http_response_code(500);
    echo json_encode(['success' => false, 'error' => $e->getMessage()]);
}

Пример использования из 1С

vbscript
// Пример отправки запроса из 1С
POST /bitrix24_proxy.php HTTP/1.1
Host: your-domain.com
Content-Type: application/json
Authorization: Bearer your-secret-auth-token

{
    "domain": "your-company.bitrix24.com",
    "method": "catalog.product.add",
    "params": {
        "fields": {
            "NAME": "Тестовый товар",
            "PRICE": 1000,
            "CURRENCY_ID": "RUB"
        }
    }
}

Источники

  1. OAuth 2.0 Protocol - Bitrix24
  2. Examples - Bitrix24 OAuth Implementation
  3. Authentication for Mobile and Desktop Applications - Bitrix24
  4. OAuth 2.0 automatic extension - Bitrix24
  5. citrus-soft/bitrix24-php-sdk - Packagist
  6. GitHub - mesilov/bitrix24-php-sdk
  7. Bitrix24 example API - GitHub Gist

Заключение

Реализация PHP-прокси для интеграции 1С с Bitrix24 API позволяет решить проблему несовместимости стандартного коннектора с OAuth-защищенными методами. Ключевые преимущества предложенного решения:

  • Универсальность: скрипт работает с любыми методами API без модификации кода
  • Автоматизация: полностью автоматическое управление OAuth токенами
  • Безопасность: безопасное хранение учетных данных и защита от несанкционированного доступа
  • Масштабируемость: поддержка множества порталов Bitrix24 из одной точки
  • Надежность: автоматическое восстановление сессий при истечении токенов

Для внедрения решения необходимо:

  1. Зарегистрировать приложение в Bitrix24 и получить учетные данные
  2. Разместить PHP-скрипт на защищенном веб-сервере
  3. Настроить перенаправление запросов из 1С на URL скрипта
  4. Реализовать обработку ответов в соответствии с требованиями 1С

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