【问题标题】:Session Persistance Issue in Phalcon PHPPhalcon PHP 中的会话持久性问题
【发布时间】:2019-03-16 02:11:41
【问题描述】:

我正在使用 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,我最终会恢复我的值。

但是当我尝试在 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 有关,但根据我有限的知识,我认为情况并非如此。

【问题讨论】:

    标签: php angularjs phalcon


    【解决方案1】:

    您确定 Angular 5 正在向 withCredentials: true 发出请求吗?

    【讨论】:

    • 不,我完全不确定。我隐约记得在我的谷歌搜索中出现了这个问题,但从未真正尝试过。当我下班回家时,我会试一试。你对它的作用有一个快速的解释吗??
    • 只需发送带有 cookie 的角度请求。你可以查看这个答案stackoverflow.com/a/47305611/4035199
    【解决方案2】:

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

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

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

    【讨论】:

    • 对于电子邮件,我去掉了很多额外内容(尝试使用 catch 进行错误处理、电子邮件登录等),但我会在原始问题中更新。至于session id,auth["id"]中存储的值其实就是用户ID。这在 Postman 中也可以正常工作(我可以发布到我的登录方法,然后如果我在 10 分钟后使用我的 getCurrentUser 方法,我会得到预期的结果。这只会在我从本地主机运行时失败或已部署的站点,并且它没有错误消息,因为它正在读取 ID(以及 Auth)为 null
    • 能否分享一下刷新页面时调用的控制器的代码?
    猜你喜欢
    • 2013-05-10
    • 2015-12-18
    • 1970-01-01
    • 1970-01-01
    • 2014-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多