Php 通过curl请求登录circle pay
我正在尝试创建一个脚本,通过Curl在PHP中登录我的pay.circle(circle pay的网站)帐户。我有问题,因为提交POST请求的响应是502错误网关消息 我不确定是否已找到登录提交的正确URL,我已使用chromes inspector查找URL,请参见以下内容: URL可能不正确,还是我没有传递正确的数据?请参见下面的我的代码:Php 通过curl请求登录circle pay,php,curl,automation,bots,Php,Curl,Automation,Bots,我正在尝试创建一个脚本,通过Curl在PHP中登录我的pay.circle(circle pay的网站)帐户。我有问题,因为提交POST请求的响应是502错误网关消息 我不确定是否已找到登录提交的正确URL,我已使用chromes inspector查找URL,请参见以下内容: URL可能不正确,还是我没有传递正确的数据?请参见下面的我的代码: $data = array( "email" => "skyrocket@yahoo.com", "passwo
$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);
我已经尝试了上面提到的各种方法,比如将post数据作为json发送。或者使用http构建函数对文本进行编码
如果您有任何指示,我们将不胜感激。(这不是关于如何登录的完整解决方案,但您犯了太多错误,无法简单地将其添加为评论文本,因此我将添加我的投诉作为答案。
)
1:本网站使用cookie进行登录会话,您需要在登录之前获取cookie(使用简单的GET请求),但您没有
2:您试图发送以多部分/表单数据
-格式编码的用户名和密码(如果您将数组赋给CURLOPT_POSTFIELDS
),则会得到该格式),但此网站使用JSON登录,因此您需要发送JSON编码的用户名和密码
3:在尝试登录之前,您需要使用有效的cookie向api.circle.com/api/v2/customers/0/sessions发送选项请求,但您没有这样做
4:本网站使用了CSRF令牌的一种变体,称为X-ECP-Session-Id
,您在获取cookie的GET请求中收到该令牌,您需要将其添加到登录请求中,但您从未获取该令牌
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
-您没有添加任何它们
难怪你的登录请求没有成功
下面是一个登录示例,使用:
因为?
不是有效的用户名,请参见第4行和第5行。(这不是关于如何登录的完整解决方案,但您犯了太多错误,无法简单地将其添加为注释文本,因此我将改为将投诉添加为答案。
)
1:本网站使用cookie进行登录会话,您需要在登录之前获取cookie(使用简单的GET请求),但您没有
2:您试图发送以多部分/表单数据
-格式编码的用户名和密码(如果您将数组赋给CURLOPT_POSTFIELDS
),则会得到该格式),但此网站使用JSON登录,因此您需要发送JSON编码的用户名和密码
3:在尝试登录之前,您需要使用有效的cookie向api.circle.com/api/v2/customers/0/sessions发送选项请求,但您没有这样做
4:本网站使用了CSRF令牌的一种变体,称为X-ECP-Session-Id
,您在获取cookie的GET请求中收到该令牌,您需要将其添加到登录请求中,但您从未获取该令牌
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
-您没有添加任何它们
难怪你的登录请求没有成功
下面是一个登录示例,使用:
因为
?
不是有效的用户名,请参见第4行和第5行。您确定该网站是支付圈
?因为根据GoogleDNS,该域不存在:。。。域名pay.circle
不存在,但域名pay.circle.com
确实存在,我猜你的意思是pay.circle.com
?你确定网站是pay.circle
?因为根据GoogleDNS,该域不存在:。。。域名pay.circle
不存在,但域名pay.circle.com
确实存在,我想你的意思是pay.circle.com
?非常感谢你的回复。我在我的问题中编辑了我的代码,我也添加了自定义标题。我能请你检查一下你的不和吗?我给你发了一个朋友请求sir@Randell您至少需要3个http请求才能登录(cookies和CSRF令牌的GET请求、OPTIONS请求和最终登录POST请求),您的代码总共只发出1个http请求,因此显然是不正确的。也就是说,重新阅读我的帖子,我添加了一个登录示例,我相信它是完全有效的。感谢您的回复。我在我的问题中编辑了我的代码,我也添加了自定义标题。我能请你检查一下你的不和吗?我给你发了一个朋友请求sir@Randell您至少需要3个http请求才能登录(cookies和CSRF令牌的GET请求、OPTIONS请求和最终登录POST请求),您的代码总共只发出1个http请求,因此显然是不正确的。也就是说,重新阅读我的帖子,我添加了一个登录示例,我相信它功能齐全
<?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