cURL等效于xhrFields:{withCredentials:true}

时间:2017-12-06 22:14:39

标签: php ajax session curl cookies

目标:

使用他们的API登录处理器的网站,并将成功响应存储到我网站上的COOKIE和SESSIONs中。

几乎有效:

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;
    }

}
?>

1 个答案:

答案 0 :(得分:1)

也许您已登录但未存储Cookie。

因此,您需要解析标题,并在最终存储所有Cookie。在处理请求时,您需要发回之前检索到的所有Cookie。

以下是如何从服务器检索Cookie和其他标头的示例:

public function sendRequest(HttpRequest $request) 
{
    ...
    curl_setopt($ch, CURLOPT_HTTPHEADER, $request->getHeaders());
    curl_setopt($ch, CURLOPT_HEADER, true);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HEADERFUNCTION, [$this, 'fetchHeader']);
    ...
    $content = curl_exec($ch);
    ...
}

/**
 * @param resource $ch     - curl handle
 * @param string   $header
 *
 * @return int
 */
private function fetchHeader($ch, $header)
{
    $headerParts = explode(': ', $header, 2);
    if (2 === count($headerParts)) {
        $headerName = strtolower($headerParts[0]);
        if ('set-cookie' === $headerName) {
            $this->responseHeaders[$headerName][] = trim($headerParts[1]);
            return strlen($header);
        }
        $this->responseHeaders[$headerName] = trim($headerParts[1]);
    }
    return strlen($header);
}