A PHP application serves Alice and Bob, and both use its server-side cURL client to reach the same remote website through a proxy. If every request loads cookies.txt, the two users can inherit the same remote login. Changing their proxy addresses does not separate that file.

Choose the cookie owner before choosing the filename. Usually it is the application's logical remote session: a local user, a particular remote account and, where needed, a separate workspace. A proxy endpoint is a routing choice, not a reliable session identifier. Several users can share one endpoint, and an endpoint can rotate exits.

Load and save the same session's jar

Let the application map its authenticated session to a server-generated file key. With a private cookie directory and a trusted $sessionKey, the cURL configuration has this shape:

$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,
]);

For a permitted public-site session test on a network allowing a public intermediary, the HTTP proxy list supplies candidate endpoints. Use a handle without configured proxy authentication or retained proxy credentials, and keep the cookie state assigned to its intended session. This fragment configures a handle; the application performs the transfer and checks its result through its normal request flow. COOKIEFILE loads prior cookies for the session. COOKIEJAR selects where the handle writes its retained cookies. Setting only the output file does not load the previous login.

A new session can start with no file. Give its first transfer the intended jar path, let the website establish the cookies, and save the resulting state for the next request. The cookie directory must be writable by the application's worker and kept outside the publicly served document tree. Do not turn a visitor-supplied username or path into a filename; look up the trusted key on the server.

Saving needs a place in the request lifecycle

libcurl normally writes the jar during handle cleanup. If the application needs an explicit save point after the remote exchange, it can request:

curl_setopt($ch, CURLOPT_COOKIELIST, 'FLUSH');

This writes the cookies currently known to the handle to its configured jar. Finish using the handle for that session before assigning it to unrelated work. Changing only the jar pathname on a handle that already holds Alice's cookies is not equivalent to creating Bob's clean session.

Also distinguish a successful download from successful persistence. The cookie-jar documentation notes that a write failure during cleanup is not returned as an ordinary transfer error. Check directory ownership, permissions and the application's diagnostic output when a login works for one request and disappears on the next.

Concurrent requests introduce another boundary. Two workers can load the same old jar, independently change their in-memory state, and then save different results. A per-session lock or equivalent serialization must cover the whole load, exchange and save sequence if both requests share one remote login; locking only the final write does not reconcile their earlier snapshots. Different sessions should have different files and independent locks.

On logout, end the intended remote session and retire its local cookie state according to the application's policy. A newly selected proxy can then be attached to whatever new session the user starts, without making the proxy address responsible for deciding whose login is in memory.

Related articles