我在 https://app.example.com
上有一个应用程序。该应用程序需要用户登录;如果他们未登录,则在尝试访问此域上的任何 URL 时,他们会被重定向到 https://app.example.com/login.php
。
当用户成功登录时,应用程序使用 native PHP session 来维护登录状态。
我们在 https://db.example.com
上有一个单独的应用程序。它是使用 CakePHP 3 构建的。它的配置使得用户将无法访问此域上的任何 URL,除非他们先通过 https://app.example.com
登录。这是通过将 session.cookie_domain
配置为 .example.com
,然后将用于 session 的 cookie 设置为 PHPSESSID
来完成的:
// config/app.php on db.example.com
'Session' => [
'defaults' => 'php',
'cookie' => 'PHPSESSID',
'timeout' => '0',
'ini' => [
'session.cookie_domain' => '.example.com',
'session.cookie_httponly' => 'off'
]
];
db.example.com
上包含一个来自 app.example.com
的脚本,该脚本针对每个请求运行。这与读取 session cookie 的能力相结合,意味着我们会在用户访问 db.example.com 上的任何内容之前检查用户是否已登录;如果没有,它们会被重定向到 app.example.com/login.php
。
到目前为止,一切正常。
问题是我正在尝试在 db.example.com
上的应用程序的一部分中向另一个应用程序发出 CURL 请求(使用 Cake 的内置功能: https://book.cakephp.org/3.0/en/core-libraries/httpclient.html ) URL 也在 db.example.com
上,但响应是 302 重定向到 https://app.example.com/login.php
。
请求是从 https://db.example.com/foo
发送到 https://db.example.com/bar
- 这也需要POST 数据中的 id
参数 - 如下所示:
// Request made by /foo:
public function foo()
{
$this->autoRender = false;
$http = new Client();
$response = $http->post('https://db.example.com/bar', [
'id' => '12345'
]);
debug($response);
}
上面的输出是一个 HTTP 302,位置设置为 app.example.com
上的登录页面:
object(Cake\Http\Client\Response) {
[protected] code => (int) 302
[protected] cookies => null
[protected] reasonPhrase => 'Found'
// ...
'Set-Cookie' => [
(int) 0 => 'PHPSESSID=g9aeqt2acol6av03rqul2puo20; path=/; domain=.example.com; secure'
],
'Location' => [
(int) 0 => 'https://app.example.com/login.php'
],
}
我已阅读Keeping session alive with Curl and PHP但不知道还需要配置什么来解决这个问题?
当 Set-Cookie
具有正确的 session /cookie/域详细信息时,我也不理解调试信息的 cookies => null
部分。
环境详细信息:
app.example.com
和db.example.com
位于同一服务器上。- 两者都使用 PHP 7.0.33
db.example.com
使用 CakePHP 3.5.13 作为框架;但app.example.com
使用普通 PHP(无框架)。- 网络服务器是 Apache 2/CentOS。
最佳答案
HTTP 客户端不会自动使用其运行的应用程序中的 cookie 或任何其他应用程序状态来自动填充自身,正如@misorude 在评论中提到的,您的代码不会将任何 cookie 设置为客户端,因此它不会发送任何内容。
您必须自己设置所需的 session cookie,例如对于单个请求,如下所示:
$data = [
'id' => '12345'
];
$config = [
'cookies' => [
//'PHPSESSID' => $this->request->getSession()->id() // before CakePHP 3.6
'PHPSESSID' => $this->getRequest()->getSession()->id()
]
];
$response = $http->post('https://db.example.com/bar', $data, $config);
假设的cookies
响应对象上的属性为空是调试显示“问题”,该类没有自定义调试输出,因此使用 PHP 默认值,其中将包括 protected 属性,如 $cookies
,但是直到您调用读取 cookie 的正确方法(即 getCookies()
)后才会填充该值。 , getCookie()
, getCookieData()
,或getCookieCollection()
.
另请参阅
关于php - 基于 CURL 和 PHP session 的身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53817354/