我对PHP的世界大部分都是新手。我目前正在尝试将Silverpop的API与我们页面上的表单进行交互。下面是我到目前为止的代码。
问题在于,虽然身份验证工作非常完美,但每当我尝试POST API所需的XML时,我总会返回一条错误消息:“会话已过期或无效。”我将在代码中标记出现错误的区域。
我花了最后半天研究,我无法弄清楚我做错了什么或者我可能缺少什么。有人告诉我,它与浏览器中的输出有关,在PHP头文件函数之前就像cURL一样,但是由于我在一个空白(没有html)的php文件中测试它,所以没有什么帮助。
<?php
// Vars
$firstname = 'a';
$lastname = 'a';
$email = 'a@b.com';
// cURL
function curl($url,$header,$postbody) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, array($header));
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postbody);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 300);
$ret = curl_exec($ch);
curl_close($ch);
return $ret;
}
///# SILVERPOP API #///
// SILVERPOP API URLs
// get_token uses oauth to retrieve an access token (works just fine)
$get_token = 'https://api1.silverpop.com/oauth/token?*inforemoved*';
$xmlapi = 'https://api1.silverpop.com/XMLAPI?Authorization=';
// XML STRINGS
$xml_post = '<Envelope><Body><AddRecipient><LIST_ID>database#</LIST_ID><CREATED_FROM>1</CREATED_FROM><SEND_AUTOREPLY>true</SEND_AUTOREPLY><UPDATE_IF_FOUND>true</UPDATE_IF_FOUND><COLUMN><NAME>Name</NAME><VALUE>'.$firstname.'</VALUE></COLUMN><COLUMN><NAME>LastName</NAME><VALUE>'.$lastname.'</VALUE></COLUMN><COLUMN><NAME>Email</NAME><VALUE>'.$email.'</VALUE></COLUMN><COLUMN><NAME>Lead Source</NAME><VALUE>Lead_SqueezePage_5Questions</VALUE></COLUMN></AddRecipient></Body></Envelope>';
$xml_done = '<Envelope><Body><Logout/></Body></Envelope>';
// HEADER VALUES
$h_access = 'Content-Type:x-www-form-urlencoded';
$h_api = 'Content-Type:text/xml;charset=UTF-8';
// Get API Access token
$auth = curl($get_token,$h_access,'');
// Pull access_token from the return string
$auth = explode('"', $auth);
for ($i=0; $i < count($auth); $i++) {
if ( $auth[$i] == "access_token" ) {
$access_token = $auth[$i + 2];
break;
}
}
//Append token to URL unless auth failed, then die
if ( $access_token != NULL) {
$xmlapi .= $access_token;
} else {
// Logout API session - SESSION ERROR HERE
$logout = curl($xmlapi,$h_api,$xml_done);
//echo 'Authentication Failed!';
die;
}
// Send Customer Data - SESSION ERROR HERE
$inject = curl($xmlapi,$h_api,$xml_post);
// Logout API Session - SESSION ERROR HERE
$logout = curl($xmlapi,$h_api,$xml_done);
///# END SILVERPOP API #///
?>
答案 0 :(得分:5)
我能够让cURL正常工作。我希望下面的代码可以帮助那些第一次使用Silverpop API并且卡住的人。
从Silverpop中检索访问密钥:
// POST Fields
$fields = array(
'client_id' => CLIENT_KEY,
'client_secret' => CLIENT_SECRET,
'refresh_token' => REFRESH_TOKEN,
'grant_type' => 'refresh_token'
);
// Init cURL
$ch = curl_init();
// Set Options
curl_setopt($ch, CURLOPT_URL, ACCESS_KEY_URL);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, count($fields));
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($fields));
// Execute cURL
$result = curl_exec($ch);
// Check for HTTP and sever errors here if you wish
// with curl_getinfo($ch, CURLINFO_HTTP_CODE)
// Close Connection
curl_close($ch);
// Now you can work with the returned $result string
向Silverpop发送XML请求信封:
// Set POST header
$header = array(
'Content-Type:text/xml;charset=UTF-8','Authorization: Bearer '.$access_key
);
// init cURL
$ch = curl_init();
// set cURL options
curl_setopt($ch, CURLOPT_URL, REQUEST_URL);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_POST, count($xml_post));
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml_post);
答案 1 :(得分:0)
我认为你需要发回cookie以保持你的会话活着。尝试将此选项添加到curl请求中。
CURLOPT_COOKIEJAR
此种类应存储cookie的文件名。如果服务器设置了任何它们将被写入该文件,并且如果它尚不存在则将被创建。
CURLOPT_COOKIEFILE
cookie jar设置是curl写入cookie的地方,但curl需要单独设置才能将cookie发送回服务器。这是CURLOPT_COOKIEFILE设置。如果未设置,则不会向服务器发送cookie。如果该文件不存在,则不会发出错误。
curl_setopt($ch, CURLOPT_COOKIEJAR, '/tmp/cookies.txt');
curl_setopt($ch, CURLOPT_COOKIEFILE, '/tmp/cookies.txt');
您需要用自己的路径替换/tmp/cookies.txt
。
答案 2 :(得分:0)
您只能在一小时内申请一定数量的访问权限 在您的代码中,看起来您正在混合OAuth授权和jsession登录/注销。
如果您有访问令牌(通过OAuth请求),请将访问令牌保存在例如会议,因为它将有效4小时。 curl标头需要在请求中包含令牌:
$curlHeaders[] = "Authorization: Bearer {$accessToken}";
当您使用用户名/密码对api进行身份验证时,将使用xml logout命令。 login命令将为您提供一个jsessionid,然后您可以在每个请求中使用(而不是访问令牌)。
我正在使用的脚本会在会话中保存访问令牌以及到期时间/日期。当Silverpop连接器触发xml命令时,它会检查访问令牌,随后检查它是否即将过期或已经过期,如果是,则请求新的令牌。
$getNewToken = true; //assume you need a new access token
//check if the session has an access token
if (!empty($_SESSION['access'])) {
//check access token is present and not expired
if ( ($expiry > (time() + 5)) && (!empty($token)) ) {
//set current access token in the Connector, no new access token required
SilverpopConnector::getInstance()->setAccessToken($token,$expiry);
$getNewToken = false;
//if the session wasn't set or token in session invalid/expired:
if ($getNewToken) {
//get access token & expiry from the Connector (will authenticate if expired/invalid)
$accessToken = SilverpopConnector::getInstance()->getAccessToken();
$tokenExpiry = SilverpopConnector::getInstance()->getAccessTokenExpiry();
//2a. if successful, set in session
//2b. if not successful, check if you're connected/re-connect
上面提到的Silverpop Connector是由GrHub上的mrmarkfrench创建的脚本。 请查看https://github.com/mrmarkfrench/silverpop-php-connector
希望这有帮助,
桑德拉。