Symfony 4 login form : authenticating successfully, but authentication immediately lost after redirect

So here are my comments in a more structured way, so that it might help someone else having problems with authentication in Symfony.

Make sure sessions are saved

By default, each session is saved as a file with the name sess_<id> in <project_dir>/var/cache/<env>/sessions or as defined by save_path in your php.ini if framework.session.handler is set to null. Configure your session directory explicitly and make sure a session file is created when you log in. If not, check the permissions for that folder.

# app/config/config.yml (Symfony 3)
# config/packages/framework.yaml (Symfony 4)
framework:
    session:
        handler_id: 'session.handler.native_file'
        save_path: '%kernel.project_dir%/var/sessions/%kernel.environment%'

Cf. https://symfony.com/doc/current/session.html#configuration

Make sure sessions are correct and used

When you login, a session with a new ID should be created. Check the content of the file. It should contain your serialized user under the firewall name (e.g. main), including your identifier (e.g. email) and your user role(s) (e.g. ROLE_USER). A problem here could be caused by faulty authentication, security config, or serialization.

_sf2_attributes|a:3:{s:18:"_csrf/authenticate";s:43:"n2oap401u4P4O7m_IhPODZ6Bz7EHl-DDsHxBEl-fhxc";s:23:"_security.last_username";s:10:"[email protected]";s:14:"_security_main";s:545:"C:67:"Symfony\Component\Security\Guard\Token\PostAuthenticationGuardToken":464:{a:2:{i:0;s:4:"main";i:1;a:5:{i:0;O:15:"App\Entity\User":4:{s:19:"App\Entity\Userid";i:1;s:22:"App\Entity\Useremail";s:10:"[email protected]";s:22:"App\Entity\Userroles";a:0:{}s:25:"App\Entity\Userpassword";s:60:"$2y$13$qwbtasafa58lPonX6B5a9eV4lziF7EZWP8NFLAe3blpCJVhQgPVOS";}i:1;b:1;i:2;a:1:{i:0;O:41:"Symfony\Component\Security\Core\Role\Role":1:{s:47:"Symfony\Component\Security\Core\Role\Rolerole";s:9:"ROLE_USER";}}i:3;a:0:{}i:4;a:1:{i:0;s:9:"ROLE_USER";}}}}";}_sf2_meta|a:3:{s:1:"u";i:1563015142;s:1:"c";i:1563015142;s:1:"l";s:1:"0";}

Check that a cookie with the same ID is set in your browser on login. The name of the cookie is defined by session.name in your php.ini, by default it is PHPSESSID. It should be sent with every request you make (e.g. Cookie: PHPSESSID=lpcf79ff8jdv2iigsgvepnr9bb). If the correct session exists, but you have a different cookie in your browser, you might have been immediately logged out after a success redirect.

Make sure the user is refreshed properly

The session ID should only change when your user changes (e.g. on login and logout). If it changes after normal requests (e.g. you are immediately logged out) or your session seems to be ignored, the problem might be that Symfony considers your user changed. This can be caused by faulty (de)serialization or comparison.

By default, Symfony uses the serialized results of getPassword(), getUsername(), and getSalt() from the session to compare against the user provided by the user provider (e.g. the database). If any of those values changes, you are logged out (cf. https://symfony.com/doc/current/security/user_provider.html#understanding-how-users-are-refreshed-from-the-session).

Thus, you should make sure that the user provided by e.g. your database is correct and matches the deserialized user from the session. Make sure the relevant fields are properly serialized. If you implement the Serializable interface, make sure your serialize() method matches your unserialize(). If you implement EquatableInterface, make sure your isEqualTo() method works correctly. Both of those interfaces are optional though, so you might consider to remove them for debugging purposes.


Happen to me a year ago, authentication succesfull, redirect and logged as anonymous. Make me want to smash my head against walls. The problem i had back then was that I created user according to an old course from KnpUniversity and it did not implement EquatableInterface and the isEqualTo method. Hope it'll work for you.

Make sure your User Entity implements EquatableInterface

namespace App\Entity;

use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\EquatableInterface;

    class User implements UserInterface, EquatableInterface
{
    private $username;
    private $password;
    private $salt;
    private $roles;

    public function __construct($username, $password, $salt, array $roles)
    {
        $this->username = $username;
        $this->password = $password;
        $this->salt = $salt;
        $this->roles = $roles;
    }

    // your setters, getters and whatever ...

    public function isEqualTo(UserInterface $user)
    {
        if (!$user instanceof WebserviceUser) {
            return false;
        }

        if ($this->password !== $user->getPassword()) {
            return false;
        }

        if ($this->salt !== $user->getSalt()) {
            return false;
        }

        if ($this->username !== $user->getUsername()) {
            return false;
        }

        return true;
    }
}

It ends that Varnish setup was the faulty.

I completely forgot that I have to specify any backoffice pattern such as /admin/ , /backoffice/ and more not to be cached by the proxy, but instead directly passed to backend.

sub vcl_recv {
    # ...
    if (req.url ~ "^/status\.php$" ||
        req.url ~ "^/update\.php$" ||
        req.url ~ "^/install\.php" ||
        req.url ~ "^/admin$" ||
        req.url ~ "^/admin/.*$" ||
        req.url ~ "^/flag/.*$" ||
        req.url ~ "^.*/ajax/.*$" ||
        req.url ~ "^.*/ahah/.*$" ||
        req.url ~ "^/info/.*$" ||
        req.url ~ "^/system/files/.*$" ||
        req.url ~ "^/user" ||
        req.url ~ "^/users/.*$" ||
        req.url ~ "^/user/.*$" ) {

       return (pass);
    }
    # ...

This was already set up for the other symfony app I mention in the question, and several Drupal websites. At least it obliged me to dig deeply in Symfony 4 User authentication process, and how to debug it ! Maybe this step by step debug post will help further readers ?!