基于 CURL 和 PHP 会话的身份验证
CURL and PHP session based authentication
我在 https://app.example.com
上有一个应用程序。该应用程序需要用户登录;如果他们 没有 登录,他们将在尝试访问此域上的任何 URL 时被重定向到 https://app.example.com/login.php
。
当用户成功登录后,应用程序使用本机 PHP 会话来维持登录状态。
我们在 https://db.example.com
上有一个单独的应用程序。这是用 CakePHP 3 构建的。它被配置为用户将无法访问此域上的任何 URL,除非他们首先通过 https://app.example.com
登录。这是通过将 session.cookie_domain
配置为 .example.com
然后将用于会话的 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'
]
];
app.example.com
在 db.example.com
上包含一个脚本,它在每次请求时运行。这与读取会话 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 但看不出还有什么配置可以解决这个问题?
我也不明白调试信息的 cookies => null
部分,当 Set-Cookie
有正确的 session/cookie/domain 细节时。
环境详细信息:
app.example.com
和 db.example.com
在同一台服务器上。
- 两者都使用PHP 7.0.33
db.example.com
使用 CakePHP 3.5.13 作为框架;但是 app.example.com
使用 vanilla PHP(无框架)。
- Web 服务器是 Apache 2 / CentOS。
HTTP 客户端不会使用来自其 运行 所在的应用程序或与此相关的任何其他应用程序状态的 cookie 自动填充自身,正如@misorude 在评论中提到的那样,您的代码不会没有向客户端设置任何 cookie,因此它不会发送任何 cookie。
您必须自己设置所需的会话 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
属性 为空是调试显示 "problem",class 没有自定义调试输出,因此 PHP 正在使用默认值,其中将包括受保护的属性,例如 $cookies
,但是在您调用读取 cookie 的正确方法之前不会填充这些属性,即 getCookies()
、getCookie()
, getCookieData()
, 或 getCookieCollection()
.
另见
我在 https://app.example.com
上有一个应用程序。该应用程序需要用户登录;如果他们 没有 登录,他们将在尝试访问此域上的任何 URL 时被重定向到 https://app.example.com/login.php
。
当用户成功登录后,应用程序使用本机 PHP 会话来维持登录状态。
我们在 https://db.example.com
上有一个单独的应用程序。这是用 CakePHP 3 构建的。它被配置为用户将无法访问此域上的任何 URL,除非他们首先通过 https://app.example.com
登录。这是通过将 session.cookie_domain
配置为 .example.com
然后将用于会话的 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'
]
];
app.example.com
在 db.example.com
上包含一个脚本,它在每次请求时运行。这与读取会话 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 但看不出还有什么配置可以解决这个问题?
我也不明白调试信息的 cookies => null
部分,当 Set-Cookie
有正确的 session/cookie/domain 细节时。
环境详细信息:
app.example.com
和db.example.com
在同一台服务器上。- 两者都使用PHP 7.0.33
db.example.com
使用 CakePHP 3.5.13 作为框架;但是app.example.com
使用 vanilla PHP(无框架)。- Web 服务器是 Apache 2 / CentOS。
HTTP 客户端不会使用来自其 运行 所在的应用程序或与此相关的任何其他应用程序状态的 cookie 自动填充自身,正如@misorude 在评论中提到的那样,您的代码不会没有向客户端设置任何 cookie,因此它不会发送任何 cookie。
您必须自己设置所需的会话 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
属性 为空是调试显示 "problem",class 没有自定义调试输出,因此 PHP 正在使用默认值,其中将包括受保护的属性,例如 $cookies
,但是在您调用读取 cookie 的正确方法之前不会填充这些属性,即 getCookies()
、getCookie()
, getCookieData()
, 或 getCookieCollection()
.
另见