duanjuelu8874 2019-03-05 15:03
浏览 94

通过curl请求登录圈付费

I am trying create a script which logs into my pay.circle (Circle Pay's website) account in PHP via Curl. I am having issues as the response from submitting the POST request is a 502 bad gateway message.

I am not sure if I have found the correct URL for the login submission, I have used chromes inspector to find the url, see below: image

Is the URL perhaps not correct or am i not passing the correct data? See my code below:

$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);

I have tried a variety of things as seen above, such as sending the post data as json. Or using the http build function to encode the text.

Any directions would be appreciated

  • 写回答

1条回答 默认 最新

  • dongzhuo8210 2019-03-06 08:52
    关注

    (this is not a full solution on how to log in, but you did too many mistakes to simply add it as comment text, so i'll add my complaints as an answer instead..)

    1: this website use cookies for login sessions, you need to fetch a cookie (with a simple GET request) before logging in, you didn't.

    2: you're trying to send the username and password encoded in multipart/form-data-format (which is what you get if you give an array to CURLOPT_POSTFIELDS), but this website use JSON to log in, so you need to send the username and password json-encoded.

    3: you need to send an OPTIONS request to api.circle.com/api/v2/customers/0/sessions with a valid cookie before attempting to log in, but you didn't.

    4: this website uses a variation of a CSRF token here called X-ECP-Session-Id which you receive together with the GET request where you get the cookie, which you need to add to the login request, but you never fetched the token in the first place.

    4: this website requires several custom http headers for the login request which you didn't add, specifically Accept: application/json, text/plain, */* and Content-Type: application/json;charset=UTF-8 and X-App-Id and X-App-Version and X-Device-Id and finally the CSRF token X-ECP-Session-Id - you didn't add any of them.

    no wonder your login request didn't succeed.

    here's a login example using 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!
    ";
        var_dump($login_errors);
        throw new \RuntimeException("LOGIN ERRORS!");
    }
    var_dump($json);
    

    which outputs:

    $ 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
    

    because ??? is not a valid username, see line 4 & 5.

    评论

报告相同问题?

悬赏问题

  • ¥15 没有证书,nginx怎么反向代理到只能接受https的公网网站
  • ¥50 成都蓉城足球俱乐部小程序抢票
  • ¥15 yolov7训练自己的数据集
  • ¥15 esp8266与51单片机连接问题(标签-单片机|关键词-串口)(相关搜索:51单片机|单片机|测试代码)
  • ¥15 电力市场出清matlab yalmip kkt 双层优化问题
  • ¥30 ros小车路径规划实现不了,如何解决?(操作系统-ubuntu)
  • ¥20 matlab yalmip kkt 双层优化问题
  • ¥15 如何在3D高斯飞溅的渲染的场景中获得一个可控的旋转物体
  • ¥88 实在没有想法,需要个思路
  • ¥15 MATLAB报错输入参数太多