我有一个设置cookie的PHP脚本(脚本A)。它是由来自不同域的AJAX JS调用调用的(所以它使用带有withCredentials标志的预检CORS)。我现在想要这个PHP脚本来CURL另一个域的PHP脚本(脚本B),以便它也设置一个cookie。但是,我在设置这些cookie时遇到了麻烦。
CURL返回成功,scriptB.php中的setcookie()返回true,但加载domainB.com页面时,浏览器中不存在cookie。
脚本B使用相同的预检CORS概念有脚本A(请忽略此代码中的安全风险,这是在概念验证阶段):
<?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失败。
感谢您提供任何帮助!
答案 0 :(得分:0)
您需要设置cookie jar,以便会话保持不变。具体来说,您需要将cookiejar和cookiefile选项设置为可读/可写文件的名称。
PS:您可以使用if(!isset($_SESSION['cookiejar'])) $_SESSION['cookiejar'] = tempnam();
$url = "http://www.domainB.com/scriptB.php";
$resp = request($url, null, null, $_SESSION['cookiejar']);
创建您的cookiejar文件。
以下是使用以下功能的示例:
/*
* Makes an HTTP request via GET or POST, and can download a file
* @returns - Returns the response of the request
* @param $url - The URL to request, including any GET parameters
* @param $params - An array of POST values to send
* @param $filename - If provided, the response will be saved to the
* specified filename
*/
private static function request($url, $params = array(), $filename = "", $cookiejar=null) {
$ch = curl_init();
$curlOpts = array(
CURLOPT_URL => $url,
// Set Useragent
CURLOPT_USERAGENT => 'Rockwell Helpdesk API',
// Don't validate SSL
// This is to prevent possible errors with self-signed certs
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true
);
if(!empty($cookiejar)){
$curlOpts[CURLOPT_COOKIEFILE] = $cookiejar;
$curlOpts[CURLOPT_COOKIEJAR] = $cookiejar;
}
if(!empty($filename)){
// If $filename exists, save content to file
$file2 = fopen($filename,'w+') or die("Error[".__FILE__.":".__LINE__."] Could not open file: $filename");
$curlOpts[CURLOPT_FILE] = $file2;
}
if (!empty($params)) {
// If POST values are given, send that shit too
$curlOpts[CURLOPT_POST] = true;
$curlOpts[CURLOPT_POSTFIELDS] = http_build_query($params);
}
curl_setopt_array($ch, $curlOpts);
$answer = curl_exec($ch);
// If there was an error, show it
if (curl_error($ch)) die(curl_error($ch));
if(!empty($filename)) fclose($file2);
curl_close($ch);
self::$lastRequest = $answer;
return $answer;
}
这是我用来登录网站和下载内容的cURL函数:
HashMap<String,List<Integer> results = new HashMap<String,List<Integer>();
// Does Key already exist?
List<Integer> temp = results.get(curve.getTenor());
if(temp != null){
//if it does add to object
temp.add(curve.getMaturitydate());
temp.add(curve.getParrate());
}else{
// if not make object and put in has map
List<Integer> nn = new ArrayList<Integer>();
nn.add(curve.getMaturitydate());
nn.add(curve.getParrate());
userList.put(curve.getTenor(), nn);
}