9

I am just trying already couple of hours to figure out how to get flash message working after logout action.

security.yml

    login:
        pattern:  ^/login$
        security: false

    secured_area:
        pattern:    ^/
        form_login:
            check_path: /check
            login_path: /login
            failure_handler: authentication_handler
        logout:
            path:   /logout
            success_handler: authentication_handler

config.yml

services:
    authentication_handler:
        class: Project\LoginBundle\Handler\AuthenticationHandler

AuthenticationHandler.php

class AuthenticationHandler implements AuthenticationFailureHandlerInterface, LogoutSuccessHandlerInterface
{
    public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
    {       
        $referer = $request->headers->get('referer');       
        $request->getSession()->setFlash('error', $exception->getMessage());

        return new RedirectResponse($referer);
    }

    public function onLogoutSuccess(Request $request) 
    {
        $referer = $request->headers->get('referer');
        $request->getSession()->setFlash('success', 'Wylogowano');


        return new RedirectResponse($referer);
    }
}

view hello after login

{% extends "ProjectCMSBundle:Secured:layout.html.twig" %}

{% block title "Hello " ~ name %}

{% block content %}
    <h1>Hello {{ name }}!</h1>

    <a href="{{ path('_project_secured_hello_admin', { 'name': name }) }}">Hello resource secured for <strong>admin</strong> only.</a>
{% endblock %}

{% set code = code(_self) %}

view login form

{% extends 'ProjectCMSBundle::layout.html.twig' %}

{% block title %}
    Title
{% endblock %}

{% block content %}


    <form action="{{ path("_project_security_check") }}" method="post" id="login">
        <div class="data">
          <div class="username">
              <label for="username">&nbsp;</label>
              <input type="text" id="username" name="_username" value="{{ last_username }}" />
          </div>

          <div class="password">
              <label for="password">&nbsp;</label>
              <input type="password" id="password" name="_password" />
          </div>
        </div>
    {% if error %}
        <div class="error">{{ error.message|trans({},'messages') }}</div>
    {% endif %}
    <input type="submit" class="submit" />
</form>
{% endblock %}

{% set code = code(_self) %}

layout main template

<!DOCTYPE html>
<html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <link rel="stylesheet" href="{{ asset('bundles/project/css/demo.css') }}" type="text/css" media="all" />
    <title>{% block title %}{% endblock %}</title>
    <link rel="shortcut icon" href="{{ asset('favicon.ico') }}" />
</head>
<body>
    <div id="symfony-wrapper">

        {% if app.session.flash('error') %}
            <div class="flash-message">
                {{ app.session.flash('error')|trans }}
            </div>
        {% endif %}

        {% if app.session.flash('success') %}
            <div class="flash-message">
                {{ app.session.flash('success')}}
            </div>
        {% endif %}

        {% if app.user %}
          {% block content_header %}
            <ul id="menu">
                {% block content_header_more %}
                {% endblock %}
            </ul>

            <div style="clear: both"></div>
          {% endblock %}
        {% endif %}

        <div class="symfony-content">
            {% block content %}
            {% endblock %}
        </div>

        {#{% if code is defined %}
            <h2>Code behind this page</h2>
            <div class="symfony-content">{{ code|raw }}</div>
        {% endif %}#}
    </div>
</body>

The problem is that it seems that flash message is getting dropped during redirect. Is there any way to accomplish this?

Thanks for the answers.

0

2 Answers 2

20

Session is destroyed on logout. But you can change this behavior by adding invalidate_session: false in your security.yml file.

logout:
    path:   /logout
    success_handler: authentication_handler
    invalidate_session: false

Check the reference documentation to have more information.

If you still want to invalidate session, you can set a flag in your Request directly and use it with a Kernel listener.

Sign up to request clarification or add additional context in comments.

2 Comments

in case of using invalidate_session Flash appears but RedirectResponse did not happened.
I would suggest considering the symfony 2.1 version - it has revamped flash messages as well as other compatibility breaks for the better.
1

Great answer from @Olivier Dolbeau but it no longer applies, now the recommended approach is to use a logout subscriber or logout listener:

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

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

    public function onLogout(LogoutEvent $event): void
    {
        // $url = '...';
        $event->setResponse(new RedirectResponse($url)); // redirect to custom URL
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.