Хранилища куки PHP cURL для отдельных сеансов пользователей
Проектирование хранения куки PHP cURL вокруг удалённого сеанса: доверенные имена файлов, явное сохранение и параллельные запросы.
PHP-приложение обслуживает Alice и Bob, и оба используют его серверный клиент cURL, чтобы через прокси попасть на один и тот же удалённый сайт. Если каждый запрос загружает cookies.txt, два пользователя могут унаследовать один и тот же удалённый вход. Смена их прокси-адресов не разделяет этот файл.
Выберите владельца куки до выбора имени файла. Обычно это логический удалённый сеанс приложения: локальный пользователь, определённая удалённая учётная запись и, при необходимости, отдельное рабочее пространство. Конечная точка прокси — это выбор маршрута, а не надёжный идентификатор сеанса. Несколько пользователей могут делить одну конечную точку, а конечная точка может менять выходы.
Загружайте и сохраняйте хранилище того же сеанса
Позвольте приложению связать свой аутентифицированный сеанс с ключом файла, созданным сервером. С закрытым каталогом куки и доверенным $sessionKey конфигурация cURL выглядит так:
$jar = $cookieDirectory . '/' . $sessionKey . '.cookies';
$ch = curl_init('https://service.example.net/account');
curl_setopt_array($ch, [
CURLOPT_PROXY => 'http://proxy.example.net:8080',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_COOKIEFILE => $jar,
CURLOPT_COOKIEJAR => $jar,
]);
Для разрешённого теста сеанса публичного сайта в сети, допускающей публичного посредника, список HTTP-прокси предоставляет подходящие конечные точки. Используйте дескриптор без настроенной аутентификации прокси или сохранённых учётных данных прокси и держите состояние куки закреплённым за нужным сеансом. Этот фрагмент настраивает дескриптор; приложение выполняет передачу и проверяет результат через обычный поток запросов. COOKIEFILE загружает предыдущие куки сеанса. COOKIEJAR выбирает, куда дескриптор пишет сохранённые куки. Установка только выходного файла не загружает предыдущий вход.
Новый сеанс может начаться без файла. Дайте его первой передаче нужный путь хранилища, позвольте сайту установить куки и сохраните полученное состояние для следующего запроса. Каталог куки должен быть доступен для записи работнику приложения и находиться вне публично обслуживаемого дерева документов. Не превращайте имя пользователя или путь, указанные посетителем, в имя файла; ищите доверенный ключ на сервере.
Сохранению нужно место в жизненном цикле запроса
libcurl обычно записывает хранилище при очистке дескриптора. Если приложению нужна явная точка сохранения после удалённого обмена, оно может запросить:
curl_setopt($ch, CURLOPT_COOKIELIST, 'FLUSH');
Это записывает куки, известные дескриптору в данный момент, в его настроенное хранилище. Завершите использование дескриптора для этого сеанса, прежде чем назначать его несвязанной работе. Смена только пути хранилища у дескриптора, который уже содержит куки Alice, не равна созданию чистого сеанса Bob.
Также отличайте успешную загрузку от успешного сохранения. Документация хранилища куки отмечает, что ошибка записи при очистке не возвращается как обычная ошибка передачи. Проверяйте владельца каталога, права и диагностический вывод приложения, когда вход работает для одного запроса и исчезает при следующем.
Параллельные запросы вводят ещё одну границу. Два работника могут загрузить одно и то же старое хранилище, независимо изменить своё состояние в памяти и затем сохранить разные результаты. Блокировка на сеанс или эквивалентная сериализация должна покрывать всю последовательность загрузки, обмена и сохранения, если оба запроса делят один удалённый вход; блокировка только финальной записи не согласует их предыдущие снимки. У разных сеансов должны быть разные файлы и независимые блокировки.
При выходе завершите нужный удалённый сеанс и отзовите его локальное состояние куки согласно политике приложения. Недавно выбранный прокси затем можно привязать к любому новому сеансу, который начнёт пользователь, не возлагая на адрес прокси решение о том, чей вход находится в памяти.