CakePHP 3:会话已经通过 Hybridauth 3 开始

CakePHP 3: Session was already started with Hybridauth 3

我有一个 LoginController,我在其中使用电子邮件地址和与帐户相关联的密码组合进行常规登录操作。

我已将我的 Hybridauth 相关代码分离到一个名为 OauthController 的单独控制器中,其中我拥有所有 Hybridauth 魔法,我的 callback / endpoint 所在。

OauthController 中,我检查来自指定提供商的用户电子邮件是否已注册,无论哪种情况,我都尝试使用 $this->Auth->setUser(object).

登录该用户

每当调用 $this->Auth 中的任何内容时,我都会收到一条响应:

Session was already started

我在浏览器中通过 CakePHP 3 代码找到了以下语句:

vendor/cakephp/cakephp/src/Network/Session.php (335)

public function start()
{
    if ($this->_started) {
        return true;
    }

    if ($this->_isCLI) {
        $_SESSION = [];
        $this->id('cli');

        return $this->_started = true;
    }

    if (session_status() === \PHP_SESSION_ACTIVE) {
        throw new RuntimeException('Session was already started');
    }

    ...

这就是向我抛出该消息的代码点。

现在,当我浏览 Hybridauth 代码本身时,我发现以下内容:

vendor/hybridauth/hybridauth/src/Storage/Session.php (46)

public function __construct()
{
    if (session_id()) {
        return;
    }

    if (headers_sent()) {
        throw new RuntimeException('HTTP headers already sent to browser and Hybridauth won\'t be able to start/resume PHP session. To resolve this, session_start() must be called before outputing any data.');
    }

    if (! session_start()) {
        throw new RuntimeException('PHP session failed to start.');
    }
}

虽然 CakePHP 的部分阻止了我,但他们都调用了 session_start,一个在另一个之前。

我已经尝试从 Hybridauth 中删除 !session_start() 检查,但是 Hybridauth 不知道在哪里读出它需要阅读的东西。

因此,作为演示者,我正在尝试在 OauthController 中实现这一点:

<?php

namespace App\Controller;

use Hybridauth\Hybridauth;

class OauthController extends AppController
{

    public function callback($provider)
    {
        try {
            $hybridauth = new Hybridauth($config);

            // additional mystery code

            $hybridauth->authenticate();

            if($everything_okay) {
                $this->Auth->setUser($userObject); // and this is the point of failure
                return $this->redirect('/account'); // and this never happends... :(
            }
        }
    }

}

欢迎任何有关如何处理此问题的帮助、想法和见解!

只需在使用 Hybridauth 库之前手动启动 CakePHP 会话,以便它在 session_id() 检查时退出并选择现有会话。

例如在您的控制器中:

$this->getRequest()->getSession()->start();

// in CakePHP versions before 3.6/3.5
// $this->request->session()->start();