Отправка cookie через cURL (CURLOPT_COOKIEFILE) не работает — потоковый API Salesforce

#php #curl #cookies #salesforce

#php #curl #файлы cookie #salesforce

Вопрос:

У меня возникли проблемы при попытке отправить файл cookie через cURL. Конкретный сценарий связан с потоковым API Salesforce, но я думаю, что это применимо к аналогичным ситуациям PHP.

Проблема в том, что выполнено 2 запроса, первый получает файл cookie с именем BAYEUX_BROWSER и использует CURLOPT_COOKIEJAR для сохранения файла cookie на сервере; второй запрос использует сохраненный файл cookie для установки сеанса.

Это фрагмент первого запроса:

 $cookie_filename = '/some/patch/cookies.txt';

$ch = curl_init();
// cURL cookie options being set
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_COOKIEJAR, $filename);
  

После выполнения запроса файл cookies.txt создается успешно, он также содержит BAYEUX_BROWSER файл cookie внутри, вот пример возвращенных файлов cookie:

 # Netscape HTTP Cookie File
# https://curl.haxx.se/docs/http-cookies.html
# This file was generated by libcurl! Edit at your own risk.

xxx.my.salesforce.com   FALSE   /cometd/    TRUE    0   BAYEUX_BROWSER  e38bvb418bj8bztzkeaan2wx18y3
#HttpOnly_xxx.my.salesforce.com FALSE   /cometd/    FALSE   0   t   !0vaFlJER5UsrfIGrfKp9YI2pARkJi5YS8O/yCf8GE 6HiX CvWWacnC3MzF OXsuC3USJWIP3jamDQ==
.salesforce.com TRUE    /   FALSE   1629832267  BrowserId   kGpyG-Y9EeqF7jOgs3LDaA
xxx.my.salesforce.com   FALSE   /   FALSE   1598388400  sfdc-stream !jH2NPGTjjg64odBoo4aJz7403s94D3xXnkFrzyha9kaRQGVKxQfnpfplyv8vwVzqy4p9godcH/z7O1A=
  

Второй запрос используется CURLOPT_COOKIEFILE для установки местоположения файла cookies и выполнения запроса с их использованием:

 $cookie_filename = '/some/patch/cookies.txt';

$ch = curl_init();
// cURL cookie options being set
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_COOKIEFILE, $filename);
  

Проблема здесь в том, что ответ от Salesforce заключается в том, что BAYEUX_BROWSER cookie отсутствует в запросе, вот точный ответ:

 400::Client xxxx has established a session, but no BAYEUX_BROWSER cookie present
  

Я уже несколько часов пытаюсь изменить и поиграть с различными параметрами cURL, чтобы посмотреть, могу ли я включить cookie, но безуспешно.

Я не уверен, нужно ли мне менять формат файлов COOKIE, или если я чего-то не хватает, я, честно говоря, не знаю на данный момент.

У кого-нибудь была подобная проблема или он знает, что не так с моим кодом?

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

1. Итак, чтобы разобраться с очевидным, ваш второй запрос на xxx.my.salesforce.com по пути /cometd/ ?

2. Кроме того, вы вызываете curl_close при первом запуске, прежде чем открыть второе соединение? Я считаю, что файлы cookie не записываются до тех пор, пока это не завершится.

3. Да, соединения закрываются между запросами, файлы cookie создаются перед вторым запросом, я проверил это.

Ответ №1:

Эта проблема решена с помощью пакета Guzzle (https://github.com/guzzle/guzzle ) вместо cURL.

 $cookie_filename = '/some/patch/cookies.json';
$jar = new GuzzleHttpCookieFileCookieJar( $filename, true );
$client = new GuzzleHttpClient();

// First response
$response = $client->request( 'POST', $url1, [
    'headers' => [...],
    'cookies' => $jar,
    'form_params' => ['message' => json_encode( $message )], 
] );

if ( $response->getStatusCode() === 200 ) {
    $response = json_decode( (string)$response->getBody() );
    // Set client ID
    $response = $client->request( 'POST', $url2, [
        'headers' => [...],
        'cookies' => $jar,
        'form_params' => ['message' => json_encode( $message )], 
    ] ); 
}