FOSUserBundle を使用した Symfony2 のおかげで Web サイトを作成しています。
同じログインで複数の接続を拒否しようとしています(ただし、たとえば異なるコンピューターから)。私は2つの解決策を持っています:
- 認証時にイベント リスナを作成しますが、作成できませんでした。(クックブックでも)。
- login_check メソッドをオーバーライドしますが、そうすると FOSUserBundle が機能しません。
より良いオプションはありますか?または解決策はありますか?
FOSUserBundle を使用した Symfony2 のおかげで Web サイトを作成しています。
同じログインで複数の接続を拒否しようとしています(ただし、たとえば異なるコンピューターから)。私は2つの解決策を持っています:
より良いオプションはありますか?または解決策はありますか?
ようやく手に入れました。すべてを解決するために行う最後の更新は 1 つだけです。User エンティティに別のフィールドを追加する必要があります。セッション ID (文字列)。次に、 LoginListener クラスを次のように更新します。
// 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);
}
}
Symfony3 では、ログアウト ハンドラーは上記のコードによってトリガーされませんでした。ユーザーがログアウトするときにシステムが更新されるように、コードを再構築します。
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);
}
}
たぶん、これは人々がこの問題を解決するのに役立つでしょう。
これは一種の解決策ですが、まだ問題があります。ユーザー セッションが php によって強制終了された場合 (たとえば、アクションなしで時間がかかりすぎた後)、データベースに移動して、「ログに記録された」値を 0 にリセットする必要があります。
だから私の解決策は次のとおりです。
- フィールド「logged」(ブール値) を User エンティティに追加します。
- YourSite\UserBundle\Listener で、次のコードを使用して : YourSiteLoginListener.php を作成します。
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);
}
}
}
-次に、同じディレクトリにログアウト ハンドラを作成します: YourSiteLogoutHandler.php
名前空間 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 これらのサービスを app/config.yml で宣言します。例:
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]