[Symfony 5]注销后的确认消息

cnwbcb6i  于 2023-02-05  发布在  其他
关注(0)|答案(6)|浏览(162)

在Symfony 5上,使用内置的登录系统,似乎无法在注销后添加确认信息,我严格按照官网上的步骤操作,可惜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');
    }
}

?>

谢谢你的帮助!

5jdjgkvh

5jdjgkvh1#

对于那些想知道如何使用新的注销定制来实现外部重定向的人:
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
3duebb1j

3duebb1j2#

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
gcxthw6b

gcxthw6b3#

多亏了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

在这种情况下,当注销时,您将被重定向到一个URL,如:/登录?注销=成功
最后,你可以在小枝模板中捕捉注销参数,如:

{%- if app.request('logout') -%}
        <div class="alert alert-success">{% trans %}Logout successful{% endtrans %}</div>
    {%- endif -%}
wfsdck30

wfsdck304#

从5.1版开始,LogoutSuccessHandlerInterface已弃用,建议使用LogoutEvent
Symfony\组件\安全\Http\注销\注销成功处理程序界面已弃用
但在正式文档中没有关于LogoutEvent的示例或信息

epfja78i

epfja78i5#

以下是LogoutEvent的文档:
https://symfony.com/blog/new-in-symfony-5-1-simpler-logout-customization
您必须创建一个事件并实现onSymfonyComponentSecurityHttpEventLogoutEvent的方法。

qfe3c7zg

qfe3c7zg6#

如果您使用的是Symfony 6及以上版本,您可以使用如下

<?php

namespace App\EventSubscriber;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Security\Http\Event\LogoutEvent;

class LogoutListener implements EventSubscriberInterface
{

    public function onLogout(LogoutEvent $logoutEvent): void
    {
        // Do your stuff
    }

    public static function getSubscribedEvents(): array
    {
        return [
            LogoutEvent::class => 'onLogout',
        ];
    }
}

相关问题