Phalcon PHP中的会话持久性问题

时间:2018-10-11 05:00:38

标签: php angularjs phalcon

我正在使用PhalconPHP,并尝试实现身份验证服务。我的前端是AngularJS 5应用程序,该应用程序使用子域上的此服务。 (可以在www.MyWebsite.com上找到我的前端,而在service.MyWebsite.com上可以找到我的服务。)到目前为止,我已经实现了以下方法来开始会话。

$di->setShared('session', function () {
    $session = new Session();
    $session->start();
    return $session;
});

然后,当用户将其用户名/密码发布到服务时,我调用loginUser方法

public function loginUser(array $userData){
    $username = $userData['username'];
    $password = $userData['password'];
    $user = Users::findFirst(
        [
            'conditions' => '(username = :username:) AND password = :password:',
            'bind' => [
                'username'    => $username,
                'password'    => $password,
             ],
             'columns' => ['users_id AS id, first, last, username, email']
        ]
    );
    $this->_registerSession($user);
    return $user->toArray();
}

用户尝试登录后,我使用_registerSession($user)方法将用户名和用户ID存放到会话中。

private function _registerSession($user){
    $this->session->set(
        "auth",
        [
            "id" => $user->id,
            "username" => $user->username,
        ]
    );   
}

此时,用户可以成功登录,因为我可以返回用户ID,名字和姓氏,用户名和电子邮件,并将用户名和ID存储在会话auth中配置。

我遇到的问题是,刷新页面时,用户将注销。

我想到的第一件事是,由于我的Angular应用程序是SPA,因此刷新页面将删除我设置为存储当前用户信息的当前全局变量。因此,为了解决此问题,我认为我需要根据会话从服务器中重新拉出信息。

因此,我为getCurrentUser()实现了一种方法

public function getCurrentUser(){
    $id = $this->session->auth["id"];
    if($id == null){
        return null;
    }
    $user = Users::findFirst(
        [
            'conditions' => 'users_id = :id:',
            'bind' => [
                'id'    => $id,
            ],
            'columns'    => "users_id AS id, first, last, username, email",
        ]
    );
    $this->_registerSession($user);
    return $user->toArray();
}

当我使用Postman进行测试时,我可以将其发布到登录端点,然后在接下来的30分钟内的任何时间,如果我致电getCurrentUser,我最终都会得到我的值。< / p>

但是当我尝试在AngularJS应用中执行此操作时,我总是在$id上得到一个空值,这告诉我它在会话中无法拉/看不到auth变量。

我已经验证了cookie中设置的PHPSESSIONID不会改变,因此sessionID应该仍然相同...那么为什么它不能从Angular应用程序中的现有会话中提取该ID,但是直接从PostMan拨打电话可以吗?

编辑 有人提到这可能是由于CORS造成的。他们删除了答案,但只是为了显示我的设置,这是我在其中附加某些标题的索引文件

if (isset($_SERVER['HTTP_ORIGIN'])) {
    // Decide if the origin in $_SERVER['HTTP_ORIGIN'] is one
    // you want to allow, and if so:
    header("Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}");
    header('Access-Control-Allow-Credentials: true');
    header('Access-Control-Max-Age: 86400');    // cache for 1 day
}

// Access-Control headers are received during OPTIONS requests
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {

    if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD']))
        // may also be using PUT, PATCH, HEAD etc
        header("Access-Control-Allow-Methods: GET, POST, OPTIONS");         

    if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']))
        header("Access-Control-Allow-Headers:{$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}");
    exit(0);
}

它可能仍然与CORS有关,但是据我有限的知识,我认为情况并非如此。

2 个答案:

答案 0 :(得分:1)

您确定5号角正在通过withCredentials: true发出请求吗?

答案 1 :(得分:0)

首先尝试获取会话ID:在getCurrentUser()中使用:

     $id = $this->session->get('auth');
     if (isset($id['id'])) {
         $user = ...

此外,在loginUser中也不要忘记将username绑定为电子邮件参数。