php - 基于 CURL 和 PHP session 的身份验证

标签 php cakephp-3.0

我在 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.comdb.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/

相关文章:

php - 由于 wamp 上可能不正确的编码/解码,特殊字符未相应显示

javascript - 如何将 php 数组格式化为 javascript 数组?

validation - CakePHP 3.x : how to edit a validation rule on the fly

CAKEPHP 3 : Select * and sum() in one statement

php - CakePHP 3 - 订单包含数据不起作用

php - 为什么备用语法 switch 语句中的输出会导致语法错误

php - 如何在PHP中计算日期时间字段和现在的差异?

php - 使用 foreach 为每组记录指定时间戳

cakephp-3.0 - Cakephp 3.0 ConnectionManager, Controller 中的getDataSource

php - 如何通过cakephp中的表单操作传递id