这是杀死用户会话的好方法:
将EventListener 与onKernelRequest 事件一起使用。在您的主代码中:public function onKernelRequest(KernelEvent $event)
$request = $event->getRequest();
$token = $this->container->get('security.token_storage')->getToken();
if ($token === null) { // somehow
return;
}
if ($token->getUser()->isLocked() === true) {
// you must implement a boolean flag on your user Entities, which the admins can set to false
$this->container->get('security.token_storage')->setToken(); // default is null, therefore null
$request->getSession()->invalidate(); // these lines will invalidate user session on next request
return;
}
现在,关于您的另一个问题:如何列出用户的在线状态?很简单,您的用户实体应该实现另一个布尔标志,例如 isOnline(带有 getter 和 setter)。
接下来,您应该创建一个LoginListener(无需实现任何接口)。在你的主代码中:
public function onSecurityInteractiveLogin(InteractiveLoginEvent $event) {
$user = $event->getAuthenticationToken()->getUser();
if ($user instanceof UserInterface) {
// set isOnline flag === true
// you will need to fetch the $user with the EntityManager ($this->em)
// make sure it exists, set the flag and then
$this->em->flush();
}
}
您的第三个事件应该是LogoutListener,您将在其中设置isOnline flag === false
当用户请求注销时,Symfony 调用 LogoutListener(作为处理程序)。
但是你可以自己写:
class LogoutListener implements LogoutHandlerInterface {
public function logout(Request $request, Response $response, TokenInterface $token): void
{
$user = $token->getUser();
if (!$user instanceof UserInterface) { /** return if user is somehow anonymous
* this should not happen here, unless... reasons */
return;
}
// else
$username = $user->getUsername(); // each user class must implement getUsername()
// get the entity Manager ($this->em, injected in your constructor)
// get your User repository
$repository = $this->em->getRepository(MyUser::class);
$user = $repository->findOneBy(['username' => $username]); // find one by username
$user->setIsOnline(false);
$this->em->flush(); // done, you've recorded a logout
}
}
希望这会有所帮助。运气好的话,它会的。干杯! :-)