如何在cakePHP3中删除特定用户的会话?

安东尼奥

我需要实现的是让管理员可以删除给定用户的会话以强制重新登录。例如,当用户权限更改时,这可能会派上用场。如何将会话和用户绑定在一起,以便其他用户可以访问该数据?

我正在使用数据库会话存储,因此从数据库中删除记录将导致强制重新登录。身份验证也基于Auth组件。

这是我的一些相关配置:

$this->loadComponent('Auth', [
            'loginAction' => [
                'controller' => 'Auth',
                'action' => 'login'
            ],
            'loginRedirect' => "/home",
            'logoutRedirect' => [
                'controller' => 'Auth',
                'action' => 'login'
            ],

            'authError' => "You have no permissions to access resource ${url}. Contact system administrator.",
            'storage' => 'Session',
            'authenticate' => [
                'Form' => [
                    'userModel' => 'User',
                    'finder' => 'user',
                    'fields' => ['username' => 'name', 'password' => 'password']
                ]
            ],
            'authorize' => ["Controller"]
        ]);

和会话存储:

   'Session' => [
        'defaults' => 'database',
]

在下面,我标记了将数据库更新代码放置在何处。不幸的是,登录执行后,会话将“重新验证”,因此ID会更改。总而言之,重定向后在登录操作中所做的更改将不可见。

登录操作:

public function login()
{
    $form = new LoginForm();
    if ($this->request->is('post')) {
        if ($form->validate($this->request->data)) {
            $user = $this->Auth->identify();
            if ($user) {
                $this->Auth->setUser($user);
                // here would be good place to update the database 
                return $this->redirect($this->Auth->redirectUrl());
            } else {
                $this->Flash->error("Invalid security credentials provided");
            }
        } else {
            $this->Flash->error("Invalid login form");
        }
    }
    $this->set('loginForm', $form);
}
安东尼奥

@ndm感谢您的宝贵意见和建议。

感谢@ndm的评论,我发现了(最有可能)可行的解决方案。我不得不在会话数据保存过程中注入一些代码。为此,我使用了customSessionHandler和PHPCloasure作为回调角色。

class UserSession extends DatabaseSession
{
    public $callback;
    public function write($id, $data)
    {
        $result = parent::write($id, $data);
        if ($this->callback) {
            call_user_func($this->callback,$id);
        }
        return $result;
    }
}

和登录操作

        $user = $this->Auth->identify();
        if ($user) {
            $this->Auth->setUser($user);
            /**  @var UserTable $model */
            $model = $this->loadModel("User");
            $handler = $this->Session->engine();
            /** @var UserSession $handler */
            $handler->callback = function ($id) use ($model, $user) {
                $model->updateSession($id, $user['id']);
            };
            return $this->redirect($this->Auth->redirectUrl());
        }

这样,在将会话数据刷新到数据库之后,将更新数据库中的会话行。

现在,我可以查询给定用户的所有会话,并在需要时将其删除,从而强制该用户重新登录。回调仅在用户登录后才被调用一次,在优化和避免UPDATE在每个http请求期间查询数据库的问题上,whitch也是我的目标(因为这也是解决方案,但我想避免这种情况)

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章