繁体   English   中英

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

[英]How to delete session for specific user in 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的评论,我发现了(最有可能)可行的解决方案。 我不得不在会话数据保存过程中注入一些代码。 为此,我使用了自定义SessionHandler和PHP的Cloasure作为回调的角色。

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());
        }

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM