[Symfony 5]注销后的确认信息
Posted
技术标签:
【中文标题】[Symfony 5]注销后的确认信息【英文标题】:[Symfony 5]Confirmation message after logout 【发布时间】:2020-07-14 20:23:57 【问题描述】:在 Symfony 5 上,使用内置的登录系统,注销后似乎无法添加确认消息。我严格按照the official website 中描述的步骤进行操作。不幸的是,SecurityController 内部的方法 logout 是没有用的。我直接在登录页面被重定向。
在这里您将获得我的 security.yaml 文件:
security:
encoders:
App\Entity\User:
algorithm: auto
# https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
providers:
# used to reload user from session & other features (e.g. switch_user)
app_user_provider:
entity:
class: App\Entity\User
property: email
# used to reload user from session & other features (e.g. switch_user)
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
anonymous: lazy
provider: app_user_provider
guard:
authenticators:
- App\Security\LoginFormAuthenticator
logout:
path: logout
target: login
remember_me:
secret: '%kernel.secret%'
lifetime: 604800 # 1 week in seconds
path: home
always_remember_me: true
# activate different ways to authenticate
# https://symfony.com/doc/current/security.html#firewalls-authentication
# https://symfony.com/doc/current/security/impersonating_user.html
# switch_user: true
# Easy way to control access for large sections of your site
# Note: Only the *first* access control that matches will be used
access_control:
- path: ^/logout$, roles: IS_AUTHENTICATED_ANONYMOUSLY
- path: ^/login$, roles: IS_AUTHENTICATED_ANONYMOUSLY
- path: ^/, roles: IS_AUTHENTICATED_FULLY
- path: ^/admin, roles: [IS_AUTHENTICATED_FULLY, ROLE_ADMIN]
- path: ^/profile, roles: [IS_AUTHENTICATED_FULLY, ROLE_USER]
还有控制器:
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
class SecurityController extends AbstractController
public function login(AuthenticationUtils $authenticationUtils): Response
if ($this->getUser())
return $this->redirectToRoute('home');
// get the login error if there is one
$error = $authenticationUtils->getLastAuthenticationError();
return $this->render('security/login.html.twig', ['last_username' => null, 'error' => $error]);
public function logout()
throw new \Exception('Don\'t forget to activate logout in security.yaml');
?>
感谢您的帮助!
【问题讨论】:
【参考方案1】:对于想知道如何通过新的注销自定义实现外部重定向的任何人:
如documentation 中所述,创建一个新的 CustomLogoutListener 类并将其添加到您的 services.yml 配置中。
CustomLogoutListener 类应该实现 onSymfonyComponentSecurityHttpEventLogoutEvent 方法,该方法将接收 LogoutEvent 作为参数,这将允许您设置响应:
namespace App\EventListener;
use JetBrains\PhpStorm\NoReturn;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Http\Event\LogoutEvent;
class CustomLogoutListener
/**
* @param LogoutEvent $logoutEvent
* @return void
*/
#[NoReturn]
public function onSymfonyComponentSecurityHttpEventLogoutEvent(LogoutEvent $logoutEvent): void
$logoutEvent->setResponse(new RedirectResponse('https://where-you-want-to-redirect.com', Response::HTTP_MOVED_PERMANENTLY));
# config/services.yaml
services:
# ...
App\EventListener\CustomLogoutListener:
tags:
- name: 'kernel.event_listener'
event: 'Symfony\Component\Security\Http\Event\LogoutEvent'
dispatcher: security.event_dispatcher.main
【讨论】:
为了避免这个长方法名称onSymfonyComponentSecurityHttpEventLogoutEvent
:在你的services.yaml
中设置method: onLogoutEvent
-Tag,这样你就可以将你的方法命名为onLogoutEvent
。【参考方案2】:
这是 LogoutEvent 的文档:
https://symfony.com/blog/new-in-symfony-5-1-simpler-logout-customization
您必须创建一个事件并实现 onSymfonyComponentSecurityHttpEventLogoutEvent 的方法。 它对我有用
【讨论】:
为了避免这个长方法名onSymfonyComponentSecurityHttpEventLogoutEvent
:在你的services.yaml
中设置method: onLogoutEvent
-Tag,这样你就可以将你的方法命名为onLogoutEvent
。【参考方案3】:
从 5.1 版本开始,LogoutSuccessHandlerInterface 已弃用,建议使用 LogoutEvent。
Symfony\Component\Security\Http\Logout\LogoutSuccessHandlerInterface 已弃用
但官方文档中没有关于LogoutEvent的示例或信息
【讨论】:
【参考方案4】:感谢 Indra Gunawan,此解决方案有效。我的目标是重定向到登录页面,并显示“您已成功注销”之类的消息。
在这种情况下,必须调整 LogoutSuccessHandler 以路由到登录页面:
namespace App\Logout;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Http\Logout\LogoutSuccessHandlerInterface;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
class MyLogoutSuccessHandler extends AbstractController implements LogoutSuccessHandlerInterface
private $urlGenerator;
public function __construct(UrlGeneratorInterface $urlGenerator)
$this->urlGenerator = $urlGenerator;
public function onLogoutSuccess(Request $request)
return new RedirectResponse($this->urlGenerator->generate('login', ['logout' => 'success']));
路由登录需要在 routes.yaml 中定义:
login:
path: /login
controller: App\Controller\SecurityController::login
logout:
path: /logout
methods: GET
在这种情况下,当您注销时,您将被重定向到如下网址:/login?logout=success
最后,您可以在 twig 模板中捕获注销参数,例如:
%- if app.request('logout') -%
<div class="alert alert-success">% trans %Logout successful% endtrans %</div>
%- endif -%
【讨论】:
【参考方案5】:SecurityController 中的 logout 方法实际上不会被命中,因为 Symfony 会拦截请求。 如果您需要在注销后执行某些操作,您可以使用注销成功处理程序
namespace App\Logout;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Http\Logout\LogoutSuccessHandlerInterface;
class MyLogoutSuccessHandler implements LogoutSuccessHandlerInterface
/**
* @inheritdoc
*/
public function onLogoutSuccess(Request $request)
// you can do anything here
return new Response('logout successfully'); // or render a twig template here, it's up to you
您可以将注销成功处理程序注册到 security.yaml
firewalls:
main:
anonymous: lazy
provider: app_user_provider
guard:
authenticators:
- App\Security\LoginFormAuthenticator
logout:
path: logout
success_handler: App\Logout\MyLogoutSuccessHandler # assume you have enable autoconfigure for servicess or you need to register the handler
【讨论】:
以上是关于[Symfony 5]注销后的确认信息的主要内容,如果未能解决你的问题,请参考以下文章
Symfony 4.4 Auth0 如何从应用程序中完全注销用户
使用 Symfony 路由从 .htaccess 重写 URL