0

I am trying to do my very first site regression testing. The site backend consists of several PHP scripts. So I've am just calling all PHP files, one after another, using cURL, with various valid and invalid input and check the result. All works fine until I reach the session-based authentication management. I see that with cURL the _SESSION does not work the same way as with normal calls to PHP from the browser (see below). If I understand correctly, this is because the session functionality requires a cookie on the client side, which is missing in case of using cURL the way I do (I kind of hoped it would happen automagically). So how do I make cURL take care of cookies and call php-files as if called by a browser?

In the example below I expect to see "test" but I see "SESSION not set" instead.

Calling file:

<?php
session_start();
$_SESSION["test"] = "test";
echo sendPost('https://rodichi.net/sandbox/php/test_curl_session_called.php', null);

function sendPost($url, $data) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    $result = curl_exec($ch);
    if ($result === false) {
        die(curl_error($ch));
    }
    curl_close($ch);
    return $result;
}

Called file:

<?php
session_start();
if (isset($_SESSION['test'])) {
    echo($_SESSION['test'].'<br>');
} else {
    echo 'SESSION not set<br>';
}
texnic
  • 3,959
  • 4
  • 42
  • 75

1 Answers1

1

cURL will transparently handle cookies for you but in order for them to persist, they either need to be saved to a file, or you need to re-use the same cURL handle on subsequent requests so the cookies will be sent.

You can enable cookie handling by calling:

curl_setopt($ch, CURLOPT_COOKIEFILE, ''); // enable cookie handling

You'd then make a request like:

curl_setopt($ch, CURLOPT_URL, 'http://some_url_that_sets_cookies');
$result = curl_exec($ch);

// without calling curl_close or destructing $ch

curl_setopt($ch, CURLOPT_URL, 'http://another_url_that_uses_cookies');
$result = curl_exec($ch);  // cookies from the previous request will be sent

cURL doesn't do anything with the $_SESSION global which associates a client to a specific session using the session ID in the cookie so your code example setting $_SESSION['test'] and then using cURL will not work as expected.

If you want to save cookies to a file after cURL is closed and then restore them later, you'd use:

curl_setopt($ch, CURLOPT_COOKIEFILE, './cookies.txt'); // load cookies from here
curl_setopt($ch, CURLOPT_COOKIEJAR', './cookies.txt'); // save cookies here when curl closes

Hope that helps.

drew010
  • 68,777
  • 11
  • 134
  • 162
  • That's clear, thanks. Still one question: If checking authentication in the called function depends on the `_SESSION` content (I check e.g. `$_SESSION['expires']`, I need somehow to read the session cookie from the file written by cURL and set the session content based on that cookie. Is it possible to do so with cURL utilities or should I just do it manually (can I actually restore a session content knowing its ID)? – texnic Mar 16 '16 at 22:32
  • I'm not really sure what you're asking. When cURL sends the proper session cookie, PHP starts the session on the remote server. Your test client for cURL will have no relation to $_SESSION, nor should it really. – drew010 Mar 16 '16 at 22:36
  • Sorry, I just realized the unclarity myself, was about to delete the comment but you were faster :) – texnic Mar 16 '16 at 23:13