Allow only one connection with the same name with FOSUserBundle

I create a site thanks to Symfony2 using FOSUserBundle.

I am triyng to prohibit multiple connections with the same login (for example, from different computers). I have 2 solutions:

  • Create a list of events for authentication, but I failed. (even with a cookbook).
  • override login_check method, but my FOSUserBundle does not work if I do this.

Do you have any better options? Or any solutions?

0
symfony connection fosuserbundle
source share
3 answers

I got it finally. To solve all this, there is only one last update. You need to add another field to the User object. sessionId (string). Then update your LoginListener class as follows:

// YourSite\UserBundle\Listener\YourSiteLoginListener.php //... public function onSecurityInteractiveLogin(InteractiveLoginEvent $event) { $request = $event->getRequest(); $session = $request->getSession(); $user = $event->getAuthenticationToken()->getUser(); $has_session = is_file ( '/path_to_your_php_session_file/'.'sess_'.$user->getSessionId() ); if($user->getLogged() && $has_session){ throw new AuthenticationException('this user is already logged'); }else{ $user->setLogged(true); $user->setSessionId($session->getId()); $this->userManager->updateUser($user); } } 
+1
source share

Perhaps this will help people solve this problem.

This is a kind of solution, but there is a problem: If the user session is killed by php (for example, after too little time without action), you need to go to your database to reset the "registered" value to 0.

So my solution is:

-add field "logged" (logical) for the user user.

- in YourSite \ UserBundle \ Listener create: YourSiteLoginListener.php using this code

 namespace YourSite\UserBundle\Listener; use FOS\UserBundle\Model\UserManagerInterface; use FOS\UserBundle\Model\UserInterface; use Symfony\Component\Security\Http\Event\InteractiveLoginEvent; use Symfony\Component\Security\Core\Exception\AuthenticationException; use Symfony\Component\Security\Core\SecurityContext; class YourSiteLoginListener { private $userManager; public function __construct(UserManagerInterface $userManager) { $this->userManager = $userManager; } public function onSecurityInteractiveLogin(InteractiveLoginEvent $event) { $user = $event->getAuthenticationToken()->getUser(); if($user->getLogged()){ throw new AuthenticationException('this user is already logged'); }else{ $user->setLogged(true); $this->userManager->updateUser($user); } } } 

- then in the same directory create an exit handler: YourSiteLogoutHandler.php

namespace YourSite \ UserBundle \ Listener;

 use FOS\UserBundle\Model\UserManagerInterface; use FOS\UserBundle\Model\UserInterface; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Security\Http\Logout\LogoutHandlerInterface; class YourSiteLogoutHandler implements LogoutHandlerInterface { private $userManager; public function __construct(UserManagerInterface $userManager) { $this->userManager = $userManager; } public function logout (Request $request, Response $response, TokenInterface $token){ $user = $token->getUser(); if($user->getLogged()){ $user->setLogged(false); $this->userManager->updateUser($user); } } } 

-finaly declare these services in your /config.yml application, for example:

 services: yoursite_login_listener: class: YourSite\UserBundle\Listener\YourSiteLoginListener arguments: [@fos_user.user_manager] tags: - { name: kernel.event_listener, event: security.interactive_login, method :onSecurityInteractiveLogin } yoursite_logout_handler: class: YourSite\UserBundle\Listener\YourSiteLogoutHandler arguments: [@fos_user.user_manager] 
0
source share

In Symfony3, the exit handler was not called by the code above. I am rebuilding the code so that the system updates when the user logs out.

 namespace YourSite\UserBundle\Listener; use FOS\UserBundle\Model\UserManagerInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\Security\Http\Logout\LogoutSuccessHandlerInterface; class LogoutSuccessHandler implements LogoutSuccessHandlerInterface { private $userManager; public function __construct(UserManagerInterface $userManager) { $this->userManager = $userManager; } public function onLogoutSuccess(Request $request){ global $kernel; $user = $kernel->getContainer()->get('security.token_storage')->getToken()->getUser(); if($user->getLogged()){ $user->setLogged(false); $this->userManager->updateUser($user); } $referer = $request->headers->get('referer'); return new RedirectResponse($referer); } } 
0
source share

All Articles