I am trying to send a cross-domain POST request from from.com to to.com using AJAX. The goal is to submit a form from from.com to to.com/process.php, where a PHP session is started, and a PHP session cookie (PHPSESSID) is generated and stored in the browser. After the session is created, the browser is redirected via JavaScript to to.com/order.php.
The POST request to to.com/process.php correctly generates a new PHP session ID and returns a Set-Cookie header with the updated PHPSESSID.
However, after the JavaScript redirect to to.com/order.php, the browser sends back a different session ID (an old/wrong one), even though a new one was generated in the process.php.
AJAX Request (from.com):
$.ajax({
type: "POST",
url: "https://to.com/process.php",
data: $("#myForm").serialize(),
xhrFields: {
withCredentials: true // Allow sending cookies with the request
},
success: function (response) {
window.location.href = "https://to.com/order.php";
}
});
to.com/process.php
<?php
header('Access-Control-Allow-Origin: https://from.com');
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Allow-Methods: POST, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, X-Requested-With');
// Handle preflight OPTIONS request
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
http_response_code(200);
exit;
}
ini_set('session.use_strict_mode', 1);
session_start();
session_regenerate_id(true);
setcookie(
'PHPSESSID',
session_id(),
[
'expires' => time() + 3600,
'path' => '/',
'domain' => 'to.com',
'secure' => true,
'httponly' => true,
'samesite' => 'None'
]
);
$_SESSION['user'] = 'John Doe';
error_log("New Session ID in process.php: " . session_id());
echo json_encode(["status" => "success"]);
exit;
?>
to.com/order.php
<?php
header('Access-Control-Allow-Origin: https://from.com');
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Allow-Methods: POST, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, X-Requested-With');
// Handle preflight OPTIONS request
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
http_response_code(200);
exit;
}
ini_set('session.use_strict_mode', 1);
session_start();
session_regenerate_id(true);
setcookie(
'PHPSESSID',
session_id(),
[
'expires' => time() + 3600,
'path' => '/',
'domain' => 'to.com',
'secure' => true,
'httponly' => true,
'samesite' => 'None'
]
);
$_SESSION['user'] = 'John Doe';
error_log("New Session ID in process.php: " . session_id());
echo json_encode(["status" => "success"]);
exit;
?>
The response headers from process.php correctly show the Set-Cookie header with a new PHPSESSID.
Why is the new session ID not being sent back correctly after a cross-domain POST request followed by a JavaScript redirect?
How can I ensure the newly generated session ID persists correctly across the redirect?