Symfony2:如何在控制器中手动记录用户?

时间:2011-06-24 07:34:17

标签: symfony

我想在控制器中做类似的事情来记录用户:

$user = $this->get('security.context')->getToken()->getUser();
$user->logOut();

6 个答案:

答案 0 :(得分:75)

Symfony2中的注销由所谓的logout处理程序处理,这只是一个lister,当URL匹配来自安全配置的模式时执行,即。如果让URL说/logout,则执行此监听器。有两个内置注销处理程序:

  1. CookieClearingLogoutHandler只清除所有Cookie。
  2. SessionLogoutHandler会话无效
  3. 你所要做的就是和最后一个一样。您可以通过简单地调用:

    来实现它

    Legacy Symfony

    $this->get('security.context')->setToken(null);
    $this->get('request')->getSession()->invalidate();
    

    Symfony 2.6

    $this->get('security.token_storage')->setToken(null);
    $this->get('request')->getSession()->invalidate();
    

    警告

    这仅在禁用remember me功能时才有效。在其他情况下,用户将通过记住我的cookie以及下一个请求再次登录。

    如果您使用“记住我”功能,请考虑使用扩展解决方案:https://stackoverflow.com/a/28828377/1056679

答案 1 :(得分:11)

使用户会话无效可能会导致一些不需要的结果。 Symfony的防火墙有一个监听器,可以始终检查和刷新用户的令牌。您可能只是重定向到您在firewall.yml

中指定的默认注销路由

在控制器中,您可以执行以下操作:

$this->redirect( $this->generateUrl( 'your_logout_url' ) );

如果您不知道注销路线的名称。您可以在控制台中查看它:

app/console router:match /logout

此命令将为您提供所需的路线名称。

:)

答案 2 :(得分:8)

我们必须在注销时将用户设置为匿名用户。然后我们可以使用
控制器中的$token->getUser()->getRoles();或树枝模板中的{% if is_granted('ROLE_USER') %}

use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken;
...
//$providerKey = $this->container->getParameter('fos_user.firewall_name');
$token = new AnonymousToken($providerKey, 'anon.');
$this->get('security.context')->setToken($token);
$this->get('request')->getSession()->invalidate();

答案 3 :(得分:1)

如果您的网站启用了rememberme功能,您还应该清理rememberme cookie:

    $this->get('security.context')->setToken(null);
    $this->get('request')->getSession()->invalidate();

    $response = new RedirectResponse($this->generateUrl('dn_send_me_the_bundle_confirm', array(
                'token' => $token
                )));
    // Clearing the cookies.
    $cookieNames = [
        $this->container->getParameter('session.name'),
        $this->container->getParameter('session.remember_me.name'),
    ];
    foreach ($cookieNames as $cookieName) {
        $response->headers->clearCookie($cookieName);
    }

答案 4 :(得分:0)

如果您使用的是symfony 4.x(我尚未测试过其他版本,因此仍然可以使用),则可能要使用symfony的内部注销处理程序(强烈建议使用,因为它将处理所有事情)干净地为您服务,包括Cookie和所有)。您也不需要为此编写太多代码,只需模拟注销请求即可:

... // Some code, that leads you to force logout the user 
// Emulating logout request
$logoutPath = $this->container->get('router')->generate('app_logout');
$logoutRequest = Request::create($logoutPath);
$logoutResponse = $this->container->get('http_kernel')->handle($logoutRequest);
// User is logged out now
... // Stuff to do after logging out, eg returning response

这将使symfony执行请求响应流,因此将在内部调用注销处理程序。此方法使您可以继续进行进一步的自定义代码。否则,如果您仅在此处调用注销侦听器,则必须返回通常的注销响应,该响应现在位于$logoutResponse中。 (可选)如果您想返回它,还可以:

return $logoutResponse;

答案 5 :(得分:0)

在Symfony 4/5中,这足以删除用户:

    /**
     * @var TokenStorageInterface $token_storage
     */
    private TokenStorageInterface $token_storage;

    /**
     * Will force logout from system
     */
    public function logoutCurrentlyLoggedInUser()
    {
        $this->token_storage->setToken(null);
    }

现在,您可以创建一种方法,以便以后使用它来检查用户是否已登录:

class Application extends AbstractController {...

    /**
     * Returns currently logged in user
     * @return object|UserInterface|null
     */
    public function getCurrentlyLoggedInUser()
    {
        return $this->getUser();
    }