【发布时间】:2016-09-15 05:15:21
【问题描述】:
我有一个设置 cookie 的 PHP 脚本(脚本 A)。它由来自不同域的 AJAX JS 调用调用(因此它使用预检 CORS 并设置了 withCredentials 标志)。我现在希望这个 PHP 脚本卷曲另一个域的 PHP 脚本(脚本 B),以便它也设置一个 cookie。但是,我无法设置这些 cookie。
CURL 成功返回,scriptB.php 中的 setcookie() 返回 true,但加载 domainB.com 页面时浏览器上不存在 cookie。
脚本 B 使用与脚本 A 相同的预检 CORS 概念(请忽略此代码中的安全风险,这是在概念验证阶段):
<?php
$allowedDomains = array('http://www.domainA.com', 'http://www.domainB.com', 'http://www.domainC.com');
// Make sure the request is from an accepted domain
if(!in_array($_SERVER['HTTP_ORIGIN'], $allowedDomains))
{
header("HTTP/1.1 403 Access Forbidden");
header("Content-Type: text/plain");
echo "Access denied";
exit;
}
// "Preflight' request required by CORS
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS')
{
// Preflight response
header('Access-Control-Allow-Origin: '.$_SERVER['REQUEST_METHOD']);
header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Max-Age: 1728000');
header("Content-Length: 0");
header("Content-Type: text/plain");
exit;
}
// Handles the actual requests
if($_SERVER['REQUEST_METHOD'] == "POST")
{
// Get the POST data
$json = file_get_contents('php://input');
$obj = json_decode($json);
if(!isset($obj->cv) || !isset($obj->e))
{
header("HTTP/1.1 403 Access Forbidden");
header("Content-Type: text/plain");
echo "Access denied.";
exit;
}
$cookieValue = $_POST['cv'];
$expires = $_POST['e'];
if(!is_numeric($expires))
{
$expires = strtotime($expires);
}
$r = setcookie('cpn_auth',$cookieValue,$expires,'/','domainB.com',false,false);
$response = array('result' => 1);
sendResponse($response);
}
/**
* Sets the reply headers and outputs the reply message
*
* @param array $response The data to send back to the requesting script
* @return void
*/
function sendResponse($response)
{
header('Access-Control-Allow-Origin: '.$_SERVER['HTTP_ORIGIN']);
header('Access-Control-Allow-Credentials: true');
header('Cache-Control: no-cache');
header('Pragma: no-cache');
header('Content-Type: text/plain');
echo json_encode($response);
exit;
}
调用此脚本的 CURL:
$post = json_encode(array('cv'=>$cv, 'e'=>$e));
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, 'http://www.domainB.com/scriptB.php');
curl_setopt($curl, CURLOPT_USERPWD, "user123:pass123");
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $post);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_TIMEOUT, 5);
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
'Content-Type: text/plain',
'Origin: http://www.domainA.com',
'Referer: http://www.domainA.com',
'Content-Length: ' . strlen($post)
));
$result = curl_exec($curl);
$return = json_decode($result, true);
curl_close($curl);
有人知道我在这里做错了什么吗?或者如果有更简单的方法?我已经看到了一些类似问题的答案,这些问题建议设置诸如 CURLOPT_COOKIE、CURLOPT_COOKIESESSION、CURLOPT_COOKIEFILE、CURLOPT_COOKIEJAR 和 CURLOPT_HEADER 之类的东西,我已经以不同的方式尝试了它们。要么没有任何变化,要么 CURL 失败。
感谢您提供的任何帮助!
【问题讨论】:
标签: php curl cookies cross-domain