我正在寻找一种方法将用户从Symfony 2应用程序中注销,但找不到合适的方法。
我尝试过这里描述的方法: Symfony2: how to log user out manually in controller?
$this->get('security.context')->setToken(null);
$this->get('request')->getSession()->invalidate();
当" remember me"" {{3}}"但是,当我启用它时,它被禁用,它无效。看起来这个cookie会再次自动重新验证用户。
remember_me:
key: "%secret%"
lifetime: 31536000
path: /
domain: ~
always_remember_me: true
将用户退出Symfony 2应用程序的正确方法是什么?我是否还需要从服务器端另外删除此cookie?
答案 0 :(得分:11)
感谢@nifr我能够解决此问题。以下是手动将用户退出Symfony 2应用程序的防弹分步指南。
Symfony已经实现了将用户注销和删除cookie的功能。有LogoutListener
人将这些操作委派给几个注销处理程序:CookieClearingLogoutHandler
和SessionLogoutHandler
。我认为最好的做法是调用那些处理程序而不是自己实现这种低级逻辑。但是,我找不到办法做到这一点。
此解决方案适用于Symfony 2.6。区别在于security.token_storage
。
parameters.yml
:# parameters.yml
parameters:
session.name: SESS
session.remember_me.name: LONGSESS
config.yml
以使用会话名称的第一个参数:# config.yml
framework:
session:
name: "%session.name%"
security.yml
以使用第二个参数记住我的会话名称:# security.yml
security:
firewalls:
demo_secured_area:
remember_me:
name: "%session.remember_me.name%"
如果需要,可以在内核事件侦听器中使用此类代码。
// SomeController.php
/**
* @Route("/terminate", name="app.terminate")
*/
public function terminateAction()
{
// Logging user out.
$this->get('security.token_storage')->setToken(null);
// Invalidating the session.
$session = $this->get('request')->getSession();
$session->invalidate();
// Redirecting user to login page in the end.
$response = $this->redirectToRoute('app.login');
// Clearing the cookies.
$cookieNames = [
$this->container->getParameter('session.name'),
$this->container->getParameter('session.remember_me.name'),
];
foreach ($cookieNames as $cookieName) {
$response->headers->clearCookie($cookieName);
}
return $response;
}
这是内核事件监听器的实现,它将强制用户基于实体属性注销:Logging user out of Symfony 2 application using kernel event listener。
我希望它有所帮助。
答案 1 :(得分:4)
您可能必须明确调用会话存储的save()
(Documentation)方法。
强制保存并关闭会话。
此外,您可以通过回复标题请求删除会话 - 和/或 remember_me -cookies。
会话 -cookie的名称配置为容器参数framework.session.name
,默认为 php.ini 中的session.name
值。
$cookieName = $this->container->getParameter('framework.session.name');
$response->headers->clearCookie( $cookieName );
可以在security
配置中配置 remember_me -cookie的名称。
security:
firewalls:
your_firewall:
remember_me:
name: neverforget # <- cookie-name
答案 2 :(得分:1)
@Slava Fomin II
Symfony已经实现了将用户注销和删除cookie的功能。有一个LogoutListener将这些操作委托给几个注销处理程序:CookieClearingLogoutHandler和SessionLogoutHandler。我认为最好的做法是调用那些处理程序而不是自己实现这种低级逻辑。但是,我找不到办法做到这一点。
为什么不简单地创建一个调用它们的服务?
我调查Symfony\Component\Security\Http\Firewall\LogoutListener
并测试他在注销期间调用了2个服务(Symfony 3.2.9)。
$tokenBasedRememberMeServices
删除了记住我的cookie。
<?php declare(strict_types=1);
namespace MyProject\Security\Listener;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
use Symfony\Component\Security\Http\Logout\DefaultLogoutSuccessHandler;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Http\Logout\SessionLogoutHandler;
use Symfony\Component\Security\Http\RememberMe\TokenBasedRememberMeServices;
final class LogoutListener
{
private $sessionLogoutHandler;
private $tokenBasedRememberMeServices;
private $defaultLogoutSuccessHandler;
private $tokenStorage;
public function __construct(
SessionLogoutHandler $sessionLogoutHandler,
TokenBasedRememberMeServices $tokenBasedRememberMeServices,
DefaultLogoutSuccessHandler $defaultLogoutSuccessHandler,
TokenStorage $tokenStorage
)
{
$this->sessionLogoutHandler = $sessionLogoutHandler;
$this->tokenBasedRememberMeServices = $tokenBasedRememberMeServices;
$this->defaultLogoutSuccessHandler = $defaultLogoutSuccessHandler;
$this->tokenStorage = $tokenStorage;
}
public function logout(Request $request): void
{
$token = $this->tokenStorage->getToken();
$response = $this->defaultLogoutSuccessHandler->onLogoutSuccess($request);
$this->sessionLogoutHandler->logout($request, $response, $token);
$this->tokenBasedRememberMeServices->logout($request, $response, $token);
}
}
答案 3 :(得分:0)
在您的security.yaml
中,您可以使用它(除其他外,此示例仅是此示例的代码):
security:
firewalls:
main:
logout:
path: app_logout
target: /login
invalidate_session: true
然后您可以执行以下操作以注销用户:
return $this->redirectToRoute('app_logout');