注销后显示Flashbag

问题描述 投票:0回答:2

我有一个网站,用户必须通过测试,最后他们可以访问测试结果。它们可以通过邮件发送,这将发送一封电子邮件,从数据库中删除记录,断开用户连接并将其重定向到登录页面。

一旦断开连接并重定向到登录页面,我想显示一条确认消息,例如“感谢您的参与!您的结果刚刚通过电子邮件发送”。

这是我在控制器内的函数中编写的内容:

$request->getSession()->getFlashBag()->add('success', 'Thanks for your participation ! ...');

return $this->redirectToRoute('app_logout');

这就是我在我的视图中写的(login_page)

{% for message in app.flashes('success') %}
    <div class="alert alert-warning alert-dismissible fade show" role="alert">
            {{ message }}
        <button type="button" class="close" data-dismiss="alert" aria-label="Close">
            <span aria-hidden="true">&times;</span>
        </button>
    </div>
{% endfor %}

我在没有断开用户连接的情况下尝试了这个,效果很好! 但是一旦我使用路由'app_logout',就不可能显示flashbag,因为用户的会话无法访问。 我还不知道要做什么,总结一下,这就是我的方向:

(查看)显示测试结果 - >(控制器)发送邮件/添加 flashbag /重定向到 app_logout 的功能 - >(?)app_logout 断开用户并重定向到 - >(查看)我想在其中显示 flashbag 的登录页面

有人知道可以做什么吗?

php symfony twig
2个回答
0
投票

最干净的解决方案可能是自定义的注销成功侦听器,它检查数据库中发送的电子邮件信息并为新会话设置闪存包(如果适用)。


0
投票

Flashbag 由

Symfony\Component\Security\Http\EventListener\SessionLogoutListener::onLogout
清理,执行:
$event->getRequest()->getSession()->invalidate()

要保留所有闪烁,只需添加另一个侦听器即可将闪烁消息重新注入到新会话中。

SessionLogoutListener
的优先级为0,因此我们需要复制优先级为1的闪光灯并将其设置为优先级-1。

<?php

namespace App\EventListener;

use Symfony\Component\EventDispatcher\Attribute\AsEventListener;
use Symfony\Component\HttpFoundation\Session\FlashBagAwareSessionInterface;
use Symfony\Component\Security\Http\Event\LogoutEvent;

#[AsEventListener(LogoutEvent::class, 'onBeforeLogout', 1)]
#[AsEventListener(LogoutEvent::class, 'onAfterLogout', -1)]
class SessionLogoutListener
{
    private array $flashes = [];

    public function onBeforeLogout(LogoutEvent $event): void
    {
        $this->flashes = [];

        $session = $event->getRequest()->hasSession() ? $event->getRequest()->getSession() : null;
        if ($session instanceof FlashBagAwareSessionInterface) {
            $this->flashes = $session->getFlashBag()->all();
        }
    }

    public function onAfterLogout(LogoutEvent $event): void
    {
        $session = $event->getRequest()->hasSession() ? $event->getRequest()->getSession() : null;
        if ($session instanceof FlashBagAwareSessionInterface) {
            $flashBag = $session->getFlashBag();
            foreach ($this->flashes as $type => $messages) {
                foreach ($messages as $message) {
                    $flashBag->add($type, $message);
                }
            }
        }

        $this->flashes = [];
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.