我想在控制器中做类似的事情来记录用户:
$user = $this->get('security.context')->getToken()->getUser();
$user->logOut();
答案 0 :(得分:75)
Symfony2中的注销由所谓的logout处理程序处理,这只是一个lister,当URL匹配来自安全配置的模式时执行,即。如果让URL说/logout
,则执行此监听器。有两个内置注销处理程序:
你所要做的就是和最后一个一样。您可以通过简单地调用:
来实现它$this->get('security.context')->setToken(null);
$this->get('request')->getSession()->invalidate();
$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();
}