【发布时间】:2018-05-20 22:15:11
【问题描述】:
目标:
使用他们的 API 登录到处理器的站点,并将成功响应存储到我站点上的 COOKIE 和 SESSION 中。
几乎可行的方法:
jQuery(document).ready(function($){
$.ajax({
type: 'POST',
url: '{url-to-api-call}',
xhrFields: {
withCredentials: true
},
dataType: 'text',
data: 'Email={email}&GuestSessionToken={token}&Password={pass}&Format=JSON&RememberMe=true',
processData: false,
crossDomain: true,
success: function (res) { console.log('success'); },
error: function (jqXHR, textStatus, ex) {
console.log('error');
}
});
});
为什么它不起作用: 我无法存储对 COOKIE 和 SESSION 的响应。
我想从事什么工作:
$url = {url-to-api};
$curl = curl_init();
$curl_post_data = array(
'Email' => $fields['user_email'],
'GuestSessionToken' => $_COOKIE['SessionToken'],
'Password' => $fields['user_pass'],
'Format' => "JSON",
'RememberMe' => "true"
);
curl_setopt($curl,CURLOPT_URL,$url);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl,CURLOPT_RETURNTRANSFER,true);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $curl_post_data);
curl_setopt($curl,CURLOPT_CONNECTTIMEOUT,5);
curl_setopt($curl, CURLOPT_TIMEOUT, 90);
$content = curl_exec($curl);
curl_close($curl);
$content_array = json_decode($content, true);
if ($content_array['StatusCode'] == 'OK') {
$fields['UserId'] = $content_array['Data']['UserId'];
$fields['SessionID'] = $content_array['Data']['ID'];
$fields['SessionToken'] = $content_array['Data']['Token'];
return true;
} else {
$errors->add( 'error', 'Unable to sign in.' );
return false;
}
为什么它不起作用: 这将返回一个成功响应,我可以使用它来设置 COOKIE 和 SESSION,但它不会让用户登录到处理器的站点。
为什么我认为它不起作用: 在我添加 xhrFields 部分之前,ajax 调用不会让用户登录。我想如果我能找到一个与 xhrFields 部分等效的 cURL,我就准备好了。
提前致谢!
我的胶带修复。
<?php
// If signin form is submitted and signin cURL was successful.
echo (isset($fields['signin_script'])) ? $fields['signin_script'] : "";
function processor_signin(&$fields, &$errors) {
$url = '{url-to-api-call}';
$curl = curl_init();
$curl_post_data = array(
'Email' => $fields['user_email'],
'GuestSessionToken' => $_COOKIE['SessionToken'],
'Password' => $fields['user_pass'],
'Format' => "JSON",
'RememberMe' => "true"
);
curl_setopt($curl,CURLOPT_URL,$url);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl,CURLOPT_RETURNTRANSFER,true);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $curl_post_data);
curl_setopt($curl,CURLOPT_CONNECTTIMEOUT,5);
curl_setopt($curl, CURLOPT_TIMEOUT, 90);
$content = curl_exec($curl);
curl_close($curl);
$content_array = json_decode($content, true);
if ($content_array['StatusCode'] == 'OK') {
$fields['UserId'] = $content_array['Data']['UserId'];
$fields['SessionID'] = $content_array['Data']['ID'];
$fields['SessionID'] = $content_array['Data']['ID'];
$fields['SessionToken'] = $content_array['Data']['Token'];
// Duct tape fix
$fields['signin_script'] = "
<script>
jQuery(document).ready(function($){
$.ajax({
type: 'POST',
url: '{url-to-api-call}',
xhrFields: {
withCredentials: true
},
dataType: 'text',
data: '
Email=".$fields['user_email']."
&GuestSessionToken=".$_COOKIE['SessionToken']."
&Password=".$fields['user_pass']."
&Format=JSON
&RememberMe=true',
processData: false,
crossDomain: true,
success: function (res) { console.log('signin success'); },
error: function (jqXHR, textStatus, ex) {
console.log('signin error');
}
});
});
</script>
";
return true;
} else {
$errors->add( 'error', 'Unable to sign in.' );
return false;
}
}
?>
【问题讨论】:
-
withCredentials是关于 CORS,告诉浏览器包含来自其他站点的 cookie。这在不存储 cookie 的 curl 中没有任何意义。您需要自己发送 cookie。 -
我希望您不要幻想您可以从您的服务器端代码在浏览器中为其他域设置 cookie ...?
-
@CBroe 使用上面的 AJAX 请求(由处理器提供)将用户登录到处理器站点并在成功时返回以下响应。 {"OK":true,"Data":{"ID":ID-HERE,"UserId":USER-ID,"Token":"TOKEN"},"StatusCode":"OK"} 如果我能弄清楚然后使用该响应在本地将 ID 和 TOKEN 设置为 COOKIE 和 SESSION 的一种方法,这是可行的。
标签: php ajax session curl cookies