Вход в круг оплаты через керл - PullRequest
1 голос
/ 05 марта 2019

Я пытаюсь создать скрипт, который входит в мою учетную запись pay.circle (веб-сайт Circle Pay) на PHP через Curl. У меня возникли проблемы, так как ответом на отправку запроса POST является сообщение о неверном шлюзе 502.

Я не уверен, что нашел правильный URL-адрес для входа в систему. Я использовал chromes инспектор, чтобы найти URL-адрес, см. Ниже: изображение

Возможно, URL неправильный или я не передаю правильные данные? Смотрите мой код ниже:

$data = array(
        "email" => "skyrocket@yahoo.com",
        "password" => "test"
        );
    $fields = json_encode($data); 

$ch = curl_init();

$url = "https://api.circle.com/api/v2/customers/0/sessions";

curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_COOKIEJAR, "cookies/logins/cookies.txt");
curl_setopt($ch, CURLOPT_COOKIEFILE, "cookies/logins/cookies.txt");
curl_setopt($ch, CURLOPT_TIMEOUT, 40000);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_REFERER, "https://pay.circle.com/signin");
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.109 Safari/537.36");
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_HTTPHEADER,  array(
'Accept: application/json, text/plain, */*',
'Origin: https://pay.circle.com',
'X-App-Version: ff40150fdea82e0f0cca84b649cabc06cc2955d3',
'X-Device-Id: {"fingerprint":"6c771befbe38d8a345506707ec6003a9","fingerprintVersion":"1.1.0","fingerprintCookie":"3d60faa3-1a9c-417f-8f3f-cf3545deb7f8"}',  
'X-ECP-Session-Id: 0000188520190305114719162707',                                                                   
'Content-Type: application/json;charset=UTF-8',                                                                                
'Content-Length: ' . strlen($fields)) );
$output = curl_exec($ch);

Я пробовал разные вещи, как показано выше, такие как отправка почтовых данных в формате json. Или используя функцию построения http для кодирования текста.

Любые указания приветствуются

1 Ответ

0 голосов
/ 06 марта 2019

(это не полное решение о том, как войти в систему, но вы сделали слишком много ошибок, чтобы просто добавить его в качестве комментария, поэтому я вместо этого добавлю свои жалобы как answer ..)

1: этот веб-сайт использует куки для сеансов входа в систему, вам нужно получить куки (с простым запросом GET), прежде чем войти, вы не сделали.

2: вы пытаетесь отправить имя пользователя и пароль в формате multipart/form-data (это то, что вы получите, если вы дадите массив для CURLOPT_POSTFIELDS), но этот сайт использует JSON для входа в систему, поэтому вы необходимо отправить имя пользователя и пароль в кодировке json.

3: вам необходимо отправить запрос OPTIONS на api.circle.com/api/v2/customers/0/sessions с действительным файлом cookie, прежде чем пытаться войти в систему, но вы этого не сделали.

4: этот веб-сайт использует вариант токена CSRF, который здесь называется X-ECP-Session-Id, который вы получаете вместе с GET-запросом, где вы получаете cookie-файл, который необходимо добавить в запрос на вход в систему, но вы никогда не выбирали токен в первое место.

4: этому веб-сайту требуются несколько пользовательских http-заголовков для запроса на вход, который вы не добавили, в частности Accept: application/json, text/plain, */* и Content-Type: application/json;charset=UTF-8 и X-App-Id и X-App-Version и X-Device-Id и, наконец, токен CSRF X-ECP-Session-Id - Вы не добавили ни одного из них.

Не удивительно, что ваш запрос на вход не прошел.

вот пример входа с использованием hhb_curl :

<?php 
declare (strict_types = 1);
require_once('hhb_.inc.php');
const USERNAME = '???';
const PASSWORD = '???';
$hc = new hhb_curl('', true);
//now to fetch the csrf token and cookies
$html = $hc->exec('https://pay.circle.com/signin')->getStdOut();
{
    // we need stuff from the headers
    $cookies_raw = $hc->getResponseHeaders();
    $cookies_parsed = array();
    foreach ($cookies_raw as $tmp) {
        if (false === strpos($tmp, ':')) {
            // don't need this header
            continue;
        }
        $tmp = explode(':', $tmp, 2);
        $cookies_parsed[trim($tmp[0])] = trim($tmp[1]);
    }
    // 'X-App-Version: ff40150fdea82e0f0cca84b649cabc06cc2955d3'
    // 'X-Device-Id: {"fingerprint":"aa1683cf1ce7dcca7a347b887747896b","fingerprintVersion":"1.1.0","fingerprintCookie":"6ad46a77-0c7e-4bd7-8570-1568f2ec8b9c"}',
    // 'X-ECP-Session-Id: 0000188520190306085938487417',
    //hhb_var_dump($cookies_parsed) & die();
    assert(isset($cookies_parsed['X-App-Version']));
    // TODO: X-Device-Id apparently comes from https://assets.circle.com/assets/javascripts/application-63066bd45540e4f6a74081aaaf96154f.js
    // assert(isset($cookies_parsed['X-Device-Id']));
    assert(isset($cookies_parsed['X-ECP-Session-Id']));
    $login_headers = array(
        'Content-Type: application/json;charset=utf-8',
        'X-App-Id: angularjs',
        'X-App-Version: ' . $cookies_parsed['X-App-Version'],
        // TODO: 'X-Device-Id: ' . $cookies_parsed['X-Device-Id'], 
        'X-ECP-Session-Id: ' . $cookies_parsed['X-ECP-Session-Id'],
    );
    //hhb_var_dump($login_headers) & die();
}

$domd = @DOMDocument::loadHTML($html);
// now do the OPTIONS request. we need to do it to log in, but it doesn't return any useful data.
$hc->setopt_array(array(
    CURLOPT_CUSTOMREQUEST => 'OPTIONS',
    CURLOPT_URL => 'https://api.circle.com/api/v2/customers/0/sessions',
    CURLOPT_HTTPHEADER => array(
        'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
        'Access-Control-Request-Method: POST',
        'Access-Control-Request-Headers: content-type,x-app-id,x-app-version,x-device-id,x-ecp-session-id',
        'Origin: https://pay.circle.com',
    )
))->exec()->setopt(CURLOPT_CUSTOMREQUEST, null);
// now to do the actual login
$json = $hc->setopt_array(array(
    CURLOPT_URL => 'https://api.circle.com/api/v2/customers/0/sessions',
    CURLOPT_POST => 1,
    CURLOPT_POSTFIELDS => json_encode(array('email' => USERNAME, 'password' => PASSWORD)),
    CURLOPT_HTTPHEADER => $login_headers
))->exec()->getStdOut();
$parsed = json_decode($json, true);
// now to look for login errors
$login_errors = [];
/*
 {
    "response": {
        "status": {
            "code": 4,
            "customerState": {
                "isEmailVerified": false,
                "isMfaVerified": false
            }
        },
        "errors": {
            "emailOrPassword": ["invalid"]
        },
        "displayErrors": ["Email or password is incorrect"],
        "displayErrorsMap": {
            "emailOrPassword": "Email or password is incorrect"
        }
    }
}
 */
$response=$parsed['response'];
if(!empty($response['errors'])){
    $login_errors[]=$response['errors'];
}
if(!empty($response['displayErrors'])){
    $login_errors[]=$response['displayErrors'];
}
if(!empty($response['displayErrors'])){
    $login_errors[]=$response['displayErrorsMap'];
}
if(!empty($login_errors)){
    echo "LOGIN ERRORS!\n";
    var_dump($login_errors);
    throw new \RuntimeException("LOGIN ERRORS!");
}
var_dump($json);

который выводит:

$ php wtf2.php
LOGIN ERRORS!
array(3) {
  [0]=>
  array(1) {
    ["emailOrPassword"]=>
    array(1) {
      [0]=>
      string(7) "invalid"
    }
  }
  [1]=>
  array(1) {
    [0]=>
    string(30) "Email or password is incorrect"
  }
  [2]=>
  array(1) {
    ["emailOrPassword"]=>
    string(30) "Email or password is incorrect"
  }
}
PHP Fatal error:  Uncaught RuntimeException: LOGIN ERRORS! in /cygdrive/c/projects/misc/wtf2.php:94
Stack trace:
#0 {main}
  thrown in /cygdrive/c/projects/misc/wtf2.php on line 94

, поскольку ??? не является допустимым именем пользователя, см. Строки 4 и 5.

...