【发布时间】:2017-11-05 13:11:50
【问题描述】:
你好 Stackoverflow 社区,
我有一个非常烦人的 PHP CURL cookie 问题,我已经尝试解决了几个月但没有成功。
我有两个 CURL 函数随后运行以将用户登录到外部站点,然后从该站点获取包含有用数据的页面。
登录功能如下:
function login($url, $data) {
$login = curl_init();
curl_setopt($login, CURLOPT_COOKIEJAR, 'cookies_' . session_id() . '.txt');
curl_setopt($login, CURLOPT_TIMEOUT, 30000);
curl_setopt($login, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($login, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($login, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($login, CURLOPT_URL, $url);
curl_setopt($login, CURLOPT_FOLLOWLOCATION, TRUE);
curl_setopt($login, CURLOPT_POST, TRUE);
curl_setopt($login, CURLOPT_POSTFIELDS, $data);
$content = curl_exec ($login);
curl_close ($login);
unset($login);
unset($data);
return $content;
}
以及使用登录功能生成的cookie文件来识别用户已登录的数据获取功能:
function grab_data($url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookies_' . session_id() . '.txt');
curl_setopt($ch, CURLOPT_TIMEOUT, 30000);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
$content = curl_exec($ch);
curl_close($ch);
unset($ch);
unset($data);
return $content;
}
现在,解决问题。登录功能工作正常,但问题是它必须将外部站点生成的 cookie 保存到服务器上的文件中。如果很多用户正在登录,这会给服务器带来很大的负载,这是不切实际的,并且是一个安全漏洞,因为它将个人用户 cookie 保存到服务器上的一个文件中,该文件可以广泛访问。 cookie 非常重要,因为它们包含会话信息,并且是数据获取功能从外部站点获取用户数据所必需的。所以,我想以某种方式在内部存储个人用户 cookie,也许在 PHP 变量中,但我很难做到这一点。我已经尝试过this 问题中建议的方法,建议将CURLOPT_HEADER 设置为true,然后使用preg_match 从标题中提取cookie,但我没有运气,因为:
- 如果我在登录功能中禁用
CURLOPT_COOKIEJAR,则登录失败。 - 如果我将
CURLOPT_COOKIEJAR设置为'-'之类的值,则登录有效,但是我在数据获取功能中遇到问题,因为我不知道如何将提取的cookie 传递给数据获取功能(我尝试了很多方法,除了CURLOPT_COOKIEFILE变体之外没有任何效果。
谁能给我一个可行的解决方案来在内部存储 cookie 并将它们传递给另一个请求?如果使用CURL 无法做到这一点,您能否建议另一种方法来完成此操作?
谢谢提前。这是一篇很长的帖子,但我想包含尽可能多的信息,以便您更好地了解我的需求。
【问题讨论】:
-
你可以先登录,然后页面拉进去,然后删除cookie。
-
@Lawrence Cherone 我已经做了你提到的,但我说过这会给服务器带来很多不必要的负载。
-
如果其中一个请求中断,30000 秒将杀死您的服务器等待。考虑将其全部卸载到作业队列,因为即使有 2 个用户也会导致“负载”。跨度>
-
糟糕!我以为那是以毫秒为单位的:D