PHP: CURL 无法保存 cookie
PHP: CURL fails to save cookie
我正在使用一台主机的 PHP 连接到同一子网中另一台主机的 API,这需要 cookie 来记住登录。它给了我一个WARNING: failed to save cookies in /var/includes/cookie
。
我为自己设置了一个简短的测试脚本如下:
$handle = curl_init();
$logfile = fopen('php://temp', 'w+');
curl_setopt_array($handle, array(
CURLOPT_URL => 'https://10.0.0.10:8443/api/login',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_COOKIEJAR => '/var/includes/cookie',
CURLOPT_COOKIEFILE => '/var/includes/cookie',
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_VERBOSE => true,
CURLOPT_STDERR => $logfile,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode(array('username' => 'user', 'password' => 'pass'))
));
$output = curl_exec($handle);
curl_close($handle); // Cookies should technically be saved here, right?
// Get contents from curl verbose log file
rewind($logfile);
$log = stream_get_contents($logfile);
fclose($logfile);
error_log($log);
error_log(print_r($output, true));
详细日志文件给我这个输出:
* Hostname in DNS cache was stale, zapped
* Trying 10.0.0.10...
* TCP_NODELAY set
* Connected to 10.0.0.10 (10.0.0.10) port 8443 (#0)
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/pki/tls/certs/ca-bundle.crt
CApath: none
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN, server did not agree to a protocol
* Server certificate:
* subject: CN=api.example.com
* start date: Oct 5 07:07:04 2020 GMT
* expire date: Jan 3 07:07:04 2021 GMT
* issuer: C=US; O=Let's Encrypt; CN=Let's Encrypt Authority X3
* SSL certificate verify ok.
> POST /api/login HTTP/1.1
Host: 10.0.0.10:8443
Accept: */*
Content-Length: 42
Content-Type: application/x-www-form-urlencoded
* upload completely sent off: 42 out of 42 bytes
< HTTP/1.1 200
< vary: Origin
< Access-Control-Allow-Credentials: true
< Access-Control-Expose-Headers: Access-Control-Allow-Origin,Access-Control-Allow-Credentials
* Added cookie xxx="some_session_id" for domain 10.0.0.10, path /, expire 0
< Set-Cookie: xxx=some_session_id; Path=/; Secure; HttpOnly
* Added cookie yyy="some_other_id" for domain 10.0.0.10, path /, expire 0
< Set-Cookie: yyy=some_other_id; Path=/; Secure
< X-Frame-Options: DENY
< Content-Type: application/json;charset=UTF-8
< Content-Length: 30
< Date: Mon, 16 Nov 2020 12:28:42 GMT
<
* Connection #0 to host 10.0.0.10 left intact
* WARNING: failed to save cookies in /var/includes/cookie
$output
本身的内容是正确的;它给了我来自 API 的 OK 信号,表明登录成功。然而,随后的请求给我的信号是我没有登录,当然是因为 cookie 没有被保存,因此没有被读取。
我试过:
- 为 cookie 使用服务的 Web 目录中的路径。
touch /var/includes/cookie
并将所有者和组设置为 apache
,具有 read/write 权限。
- 对文件设置 777 权限。
sudo -u apache bash
获取终端并尝试修改文件 - 这行得通,那么文件权限肯定没问题吗?
有什么我应该看的地方吗? SELinux 会影响这个吗?我的问题看起来类似于 this one。
CentOS 8,PHP7.2.11,libcurl 7.61.1
事实证明,是 SELinux 的尝试。提到问题的解决方案感觉有点傻,但我知道我不是第一个被 SELinux 绊倒的人。
首先,为了测试这是否真的是问题所在,您可以暂时将其关闭(如果这样做对您来说是安全的)。
setenforce 0
如果可行,我当然会建议将其重新打开,而不是为需要修改的文件设置规则。
setenforce 1
因为我在 /var/includes/cookie
有文件,所以我会 运行 以下命令来添加持久规则:
semanage fcontext -a -t httpd_sys_rw_content_t /var/includes/cookie
-a
添加一条记录
-t
指定了一种新类型,在本例中为可由 httpd 写入的类型
编写上下文规则后,仍需应用它:
restorecon -v /var/includes/cookie
-v
以获得关于更改内容的一些输出
有关更深入的说明,请参阅 this guide。
另外值得注意:我必须安装 policycoreutils-python-utils
软件包才能在我的最小 CentOS 系统上获取 semanage
命令。
我正在使用一台主机的 PHP 连接到同一子网中另一台主机的 API,这需要 cookie 来记住登录。它给了我一个WARNING: failed to save cookies in /var/includes/cookie
。
我为自己设置了一个简短的测试脚本如下:
$handle = curl_init();
$logfile = fopen('php://temp', 'w+');
curl_setopt_array($handle, array(
CURLOPT_URL => 'https://10.0.0.10:8443/api/login',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_COOKIEJAR => '/var/includes/cookie',
CURLOPT_COOKIEFILE => '/var/includes/cookie',
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_VERBOSE => true,
CURLOPT_STDERR => $logfile,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode(array('username' => 'user', 'password' => 'pass'))
));
$output = curl_exec($handle);
curl_close($handle); // Cookies should technically be saved here, right?
// Get contents from curl verbose log file
rewind($logfile);
$log = stream_get_contents($logfile);
fclose($logfile);
error_log($log);
error_log(print_r($output, true));
详细日志文件给我这个输出:
* Hostname in DNS cache was stale, zapped
* Trying 10.0.0.10...
* TCP_NODELAY set
* Connected to 10.0.0.10 (10.0.0.10) port 8443 (#0)
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/pki/tls/certs/ca-bundle.crt
CApath: none
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN, server did not agree to a protocol
* Server certificate:
* subject: CN=api.example.com
* start date: Oct 5 07:07:04 2020 GMT
* expire date: Jan 3 07:07:04 2021 GMT
* issuer: C=US; O=Let's Encrypt; CN=Let's Encrypt Authority X3
* SSL certificate verify ok.
> POST /api/login HTTP/1.1
Host: 10.0.0.10:8443
Accept: */*
Content-Length: 42
Content-Type: application/x-www-form-urlencoded
* upload completely sent off: 42 out of 42 bytes
< HTTP/1.1 200
< vary: Origin
< Access-Control-Allow-Credentials: true
< Access-Control-Expose-Headers: Access-Control-Allow-Origin,Access-Control-Allow-Credentials
* Added cookie xxx="some_session_id" for domain 10.0.0.10, path /, expire 0
< Set-Cookie: xxx=some_session_id; Path=/; Secure; HttpOnly
* Added cookie yyy="some_other_id" for domain 10.0.0.10, path /, expire 0
< Set-Cookie: yyy=some_other_id; Path=/; Secure
< X-Frame-Options: DENY
< Content-Type: application/json;charset=UTF-8
< Content-Length: 30
< Date: Mon, 16 Nov 2020 12:28:42 GMT
<
* Connection #0 to host 10.0.0.10 left intact
* WARNING: failed to save cookies in /var/includes/cookie
$output
本身的内容是正确的;它给了我来自 API 的 OK 信号,表明登录成功。然而,随后的请求给我的信号是我没有登录,当然是因为 cookie 没有被保存,因此没有被读取。
我试过:
- 为 cookie 使用服务的 Web 目录中的路径。
touch /var/includes/cookie
并将所有者和组设置为apache
,具有 read/write 权限。- 对文件设置 777 权限。
sudo -u apache bash
获取终端并尝试修改文件 - 这行得通,那么文件权限肯定没问题吗?
有什么我应该看的地方吗? SELinux 会影响这个吗?我的问题看起来类似于 this one。
CentOS 8,PHP7.2.11,libcurl 7.61.1
事实证明,是 SELinux 的尝试。提到问题的解决方案感觉有点傻,但我知道我不是第一个被 SELinux 绊倒的人。
首先,为了测试这是否真的是问题所在,您可以暂时将其关闭(如果这样做对您来说是安全的)。
setenforce 0
如果可行,我当然会建议将其重新打开,而不是为需要修改的文件设置规则。
setenforce 1
因为我在 /var/includes/cookie
有文件,所以我会 运行 以下命令来添加持久规则:
semanage fcontext -a -t httpd_sys_rw_content_t /var/includes/cookie
-a
添加一条记录-t
指定了一种新类型,在本例中为可由 httpd 写入的类型
编写上下文规则后,仍需应用它:
restorecon -v /var/includes/cookie
-v
以获得关于更改内容的一些输出
有关更深入的说明,请参阅 this guide。
另外值得注意:我必须安装 policycoreutils-python-utils
软件包才能在我的最小 CentOS 系统上获取 semanage
命令。