我正在尝试将https://github.com/simon-weber/gpsoauth移植到PHP。
当我从命令行执行curl请求时,响应符合预期:
命令:
curl "https://android.clients.google.com/auth" --data "Email=<EMAIL>&Passwd=<PASSWD>&service=ac2dm&add_account=1"
响应:
SID=BAD_COOKIE
LSID=BAD_COOKIE
Auth=DQAAABEB....
services=mail,talk,ig,writely,reader...
Email=...
Token=oauth2rt_1/...
GooglePlusUpgrade=0
firstName=...
lastName=...
但是,当我尝试使用PHP curl进行相同的调用时,Token
缺失。
代码:
$data = [
'Email' => $email,
'add_account' => 1,
'Passwd' => $passwd,
'service' => 'ac2dm',
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://android.clients.google.com/auth');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
$response = curl_exec($ch);
curl_close($ch);
响应:
SID=BAD_COOKIE
LSID=BAD_COOKIE
Auth=DQAAABEB....
services=mail,talk,ig,writely,reader...
Email=...
GooglePlusUpgrade=0
firstName=...
lastName=...
我尝试使用file_get_contents
甚至是shell_exec
,但结果是一样的。 Google接受我的凭据,但未发送Token
为什么PHP Curl表现不同?我是否必须添加或删除某些标题?
答案 0 :(得分:0)
谢谢@Paras。
两个请求之间的唯一区别是内容长度 - 卷曲为80而PHP为82。
我的密码中有一个感叹号,http_build_query()
替换为%21
,而命令行上的curl
则没有。
Google似乎同时接受这两者,但只有Token
才会发送!
,而不是%21
。
答案 1 :(得分:0)
不要使用http_build_query
,它用于查询字符串数据,而不是application/x-www-form-urlencoded
。当!
正文的一部分时,POST
不应编码。您可以直接传递数组作为CURLOPT_POSTFIELDS
的值。请参阅http://php.net/manual/en/function.curl-setopt.php上的相关说明。
RFC 1738说:
因此,只有字母数字,特殊字符“$ -_。+!*'(),”和 可以使用用于其保留目的的保留字符 在URL中未编码。