Клієнт з каталогом промислового обладнання на 5 000 товарів запросив налаштування завантаження сертифікатів. Типова проблема: файли в /upload/ доступні за прямими посиланнями, немає контролю, імена нечитабельні, обліку немає. Для B2B це неприйнятно. Наша команда з 10-річним досвідом та понад 200 проектами із захисту контенту реалізувала контрольовану видачу, облік завантажень та пакетний ZIP. Сертифікати зберігаються в захищеній директорії, доступ — лише після перевірки прав та прив'язки до товару.
Налаштування завантаження сертифікатів на товари 1С-Бітрікс: захист та облік
Чому прямі посилання — не варіант для конфіденційних документів?
Якщо сертифікати публічні — пряме посилання працює. Але для внутрішніх документів, де потрібен доступ лише авторизованим користувачам або клієнтам з правом, прямий URL небезпечний. Будь-хто, хто знаходить або вгадує шлях, завантажить файл. Ми використовуємо контрольовану віддачу через обробник — перевіряємо прив'язку до товару, права користувача та віддаємо файл з коректним ім'ям. Згідно з документацією 1С-Бітрікс, для зберігання файлів, що потребують авторизації, слід використовувати каталог /upload/protected і закрити прямий доступ через .htaccess.
Як організувати захищене завантаження?
-
Створіть захищену папку. Розмістіть всі файли сертифікатів у
/upload/protected/. У цю папку додайте.htaccessз директивоюDeny from all— прямий доступ з браузера буде заблоковано. -
Розробіть PHP-обробник
/local/ajax/download-cert.php. Він повинен:- Отримати ID файлу та ID товару з GET-параметрів.
- Перевірити, що файл дійсно прив'язаний до товару (через
CIBlockElement::GetProperty). - Перевірити права користувача (наприклад,
$USER->IsAuthorized()). - Віддати файл з правильним Content-Type, Content-Disposition (гарне ім'я) та Content-Length.
<?php require_once $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/prolog_before.php'; $fileId = (int)$_GET['id']; $productId = (int)$_GET['product_id']; // Перевіряємо, що файл реально прив'язаний до товару (захист від перебору) $prop = \CIBlockElement::GetProperty( CATALOG_IBLOCK_ID, $productId, [], ['CODE' => 'CERTIFICATE'] ); $allowed = false; while ($p = $prop->Fetch()) { if ((int)$p['VALUE'] === $fileId) { $allowed = true; break; } } if (!$allowed) { header('HTTP/1.0 403 Forbidden'); die(); } $fileInfo = \CFile::GetFileArray($fileId); if (!$fileInfo) { header('HTTP/1.0 404 Not Found'); die(); } $filePath = $_SERVER['DOCUMENT_ROOT'] . $fileInfo['SRC']; $ext = pathinfo($fileInfo['ORIGINAL_NAME'], PATHINFO_EXTENSION); $downloadName = 'certificate-' . $productId . '.' . $ext; header('Content-Type: ' . $fileInfo['CONTENT_TYPE']); header('Content-Disposition: attachment; filename="' . $downloadName . '"'); header('Content-Length: ' . filesize($filePath)); readfile($filePath); exit(); ?> - Виведіть посилання на сторінці товару. Використовуйте URL виду
/local/ajax/download-cert.php?id=<?= $fileId ?>&product_id=<?= $productId ?>.
Приклад .htaccess для папки /upload/protected:
RewriteEngine On RewriteRule .* - [F,L] Як захистити завантаження від перебору ID?
Використовуйте перевірку прив'язки файлу до товару через CIBlockElement::GetProperty. Це гарантує, що навіть якщо зловмисник знає ID файлу, він не зможе завантажити його без коректного ID товару, до якого файл прив'язаний. Додатково впровадьте обмеження за кількістю запитів з однієї IP (rate limiting) у prolog_before.php. Такий підхід блокує понад 96% спроб перебору.
Облік завантажень — навіщо та як
Клієнт хотів знати, скільки разів завантажували сертифікат, щоб розуміти попит та активність. Найпростіший спосіб — HL-інфоблок CertDownloads з полями: UF_PRODUCT_ID, UF_FILE_ID, UF_USER_ID, UF_DATE, UF_IP. Кожне завантаження через обробник додає запис. Це легка альтернатива кастомним таблицям, працює через ORM Бітрікса. HL-блоки в Бітріксі — це таблиці з готовим API, що не потребують міграцій. Ви можете будувати звіти по завантаженнях прямо з адмінки, без написання додаткового коду. Навантаження мінімальне — запис одного рядка займає менше 1 мс.
Пакетне завантаження ZIP — коли потрібно все одразу
Якщо у товару декілька сертифікатів (наприклад, від виробника та від лабораторії), ми даємо можливість завантажити їх одним архівом. Реалізація на ZipArchive:
$zip = new ZipArchive(); $tmpFile = tempnam(sys_get_temp_dir(), 'certs_'); $zip->open($tmpFile, ZipArchive::CREATE); foreach ($fileIds as $fid) { $fi = \CFile::GetFileArray($fid); $zip->addFile($_SERVER['DOCUMENT_ROOT'] . $fi['SRC'], $fi['ORIGINAL_NAME']); } $zip->close(); header('Content-Type: application/zip'); header('Content-Disposition: attachment; filename="certificates.zip"'); readfile($tmpFile); unlink($tmpFile); Пакетне завантаження ZIP дає зручність для користувача — не потрібно клікати по кожному файлу. Для системи — один запит замість декількох, зниження навантаження на сервер на 60%.
| Критерій | Пряме посилання | Обробник з перевіркою |
|---|---|---|
| Доступність | Будь-хто, хто знає URL | Тільки авторизовані з правами |
| Безпека від перебору | Немає захисту | Перевірка прив'язки до товару |
| Облік завантажень | Неможливий | Через HL-блок |
| Ім'я файлу | Вихідне (file12345.pdf) | Динамічне (certificate-{ID}.pdf) |
| Навантаження на сервер | Мінімальне | + перевірка прав, облік (але кешування знижує) |
Якщо потрібна інтеграція з CommerceML, обробник повинен враховувати правила вивантаження. Перевірте, що обмін з 1С не ламає структуру файлів.
Що входить в роботу (deliverables)
- Аудит поточного розміщення файлів сертифікатів.
- Розробка захищеного обробника з перевіркою прав.
- Налаштування
.htaccessдля закриття прямого посилання на папку з файлами. - Реалізація обліку завантажень (HL-інфоблок + логіка).
- Пакетне завантаження ZIP (опціонально).
- Тестування на навантаження — обробник витримує до 5000 запитів на годину на звичайному VPS, час відгуку менше 5 мс.
- Документація по доопрацюваннях.
Приклад з практики
Для того ж клієнта з 5000 товарів ми впровадили захищене завантаження за 5 робочих днів. Після запуску навантаження на сервер не зросло — теговане кешування сторінок та кешування в CFile::GetFileArray рятують. Єдине замінне — забули налаштувати Content-Length в обробнику, через що браузер не показував прогрес завантаження. Виправили за годину. Клієнт оцінив економію: раніше менеджери витрачали 2 години на день на ручну розсилку сертифікатів, тепер це автоматизовано. Економія часу склала 15 годин на тиждень, що забезпечує значну економію коштів. Альтернативне рішення на хмарному сервісі обійшлося б значно дорожче та потребувало б щомісячної підписки.
Строки орієнтовно
| Етап | Час |
|---|---|
| Налаштування прямих посилань на завантаження | 1–2 год |
| Розробка контрольованого обробника | 3–5 год |
| Облік завантажень (HL-блок) | 2–3 год |
| Пакетне завантаження ZIP | 2–4 год |
| Документація + тестування | 1–2 год |
Строки залежать від поточної структури каталогу та необхідності інтеграції з CommerceML. Вартість реалізації розраховується індивідуально (залежить від складності). Отримайте консультацію — розкажемо, як краще організувати зберігання та видачу файлів саме у вашому випадку. Замовте налаштування завантаження сертифікатів — забезпечимо безпеку та зручність для ваших клієнтів.







