我需要从Python到PHP移植一个脚本,该脚本通过POST请求登录到API。在python中,我会这样做:
import requests
response = requests.post(api_url, data={"username": user, "password": pw})
,然后在检查response.content
时,我会得到所需的身份验证信息。
但是,当将其移植到PHP时,我得到的响应不是带有所需数据的经过身份验证的页面,而是未经身份验证的版本,与在签名之前在Web浏览器中打开它所获得的响应类似。进入我的帐户。
这是该脚本的PHP版本:
function http_post($url, $data) {
$data = http_build_query($data);
$opts = array("http" => array(
"method" => "POST",
"content" => $data
));
$context = stream_context_create($opts);
$fp = fopen($url, "rb", false, $context);
if (!$fp) {
return false;
}
$content = stream_get_contents($fp);
fclose($fp);
return $content;
}
function log_into_api($user, $pw) {
// I use "echo" here just as an example. IRL there's more processing
// Before any information is displayed to the user.
echo http_post($api_url, array("username" => $user, "password" => $pw))
}
log_into_api("foo", "bar");
为什么会这样?肯定不是因为标头(因为它在Python中有效,在这里我也不使用标头)对吗?
注意:我不能在此PHP脚本中使用第三方库,例如curl。
使用stream_context_create
也不起作用,尽管这会使代码更加整洁。
function http_post_flds($url, $data, $headers=NULL) {
$data = http_build_query($data);
$opts = array('http' => array(
'method' => 'POST',
'content' => $data
));
if ($headers) {
$opts["http"]["headers"] = $headers;
}
$context = stream_context_create($opts);
return file_get_contents($url, false, $context);
}
我还尝试使用Content-type
标头调用此函数,如下所示:
function log_into_api($user, $pw) {
// I use "echo" here just as an example. IRL there's more processing
// Before any information is displayed to the user.
echo http_post($api_url,
array("username" => $user, "password" => $pw),
array("Content-Type => application/x-www-form-urlencoded")
);
}
像这样:
function log_into_api($user, $pw) {
// I use "echo" here just as an example. IRL there's more processing
// Before any information is displayed to the user.
echo http_post($api_url,
array("username" => $user, "password" => $pw),
array("Content-Type => multipart/form-data")
);
}
但是这些都不起作用。
最后,我再次启动了Python,并print
编辑了原始的response.request.headers
,如下所示:
{
'User-Agent': 'python-requests/2.20.0',
'Accept-Encoding': 'gzip, deflate',
'Accept': '*/*',
'Connection': 'keep-alive'
}
之后,我尝试在PHP脚本上使用这些标头,如下所示:
function log_into_api($user, $pw) {
// I use "echo" here just as an example. IRL there's more processing
// Before any information is displayed to the user.
echo http_post($api_url,
array("username" => $user, "password" => $pw),
array(
'User-Agent' => 'python-requests/2.20.0',
'Accept-Encoding' => 'gzip, deflate',
'Accept' => '*/*',
'Connection' => 'keep-alive'
)
);
}