Automatic post-registration user authentication Automatic post-registration user authentication symfony symfony

Automatic post-registration user authentication


Symfony 4.0

This process hasn't changed from Symfony 3 to 4 but here is an example using the newly recommended AbstractController. Both the security.token_storage and the session services are registered in the parent getSubscribedServices method so you don't have to add those in your controller.

use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;use YourNameSpace\UserBundle\Entity\User;class LoginController extends AbstractController{    public function registerAction()    {            $user = //Handle getting or creating the user entity likely with a posted form        $token = new UsernamePasswordToken($user, null, 'main', $user->getRoles());        $this->container->get('security.token_storage')->setToken($token);        $this->container->get('session')->set('_security_main', serialize($token));        // The user is now logged in, you can redirect or do whatever.    }}

Symfony 2.6.x - Symfony 3.0.x

As of Symfony 2.6 security.context is deprecated in favor of security.token_storage. The controller can now simply be:

use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;use Symfony\Bundle\FrameworkBundle\Controller\Controller;use YourNameSpace\UserBundle\Entity\User;class LoginController extends Controller{    public function registerAction()    {            $user = //Handle getting or creating the user entity likely with a posted form        $token = new UsernamePasswordToken($user, null, 'main', $user->getRoles());        $this->get('security.token_storage')->setToken($token);        $this->get('session')->set('_security_main', serialize($token));    }}

While this is deprecated you can still use security.context as it has been made to be backward compatible. Just be ready to update it for Symfony 3.

You can read more about the 2.6 changes for security here: https://github.com/symfony/symfony/blob/2.6/UPGRADE-2.6.md

Symfony 2.3.x

To accomplish this in Symfony 2.3 you can no longer just set the token in the security context. You also need to save the token to the session.

Assuming a security file with a firewall like:

// app/config/security.ymlsecurity:    firewalls:        main:            //firewall settings here

And a controller action similar to:

use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;use Symfony\Bundle\FrameworkBundle\Controller\Controller;use YourNameSpace\UserBundle\Entity\User;class LoginController extends Controller{    public function registerAction()    {            $user = //Handle getting or creating the user entity likely with a posted form        $token = new UsernamePasswordToken($user, null, 'main', $user->getRoles());        $this->get('security.context')->setToken($token);        $this->get('session')->set('_security_main',serialize($token));        //Now you can redirect where ever you need and the user will be logged in    }}

For the token creation you will want to create a UsernamePasswordToken. This accepts 4 parameters: User Entity, User Credentials, Firewall Name, User Roles. You don't need to provide the user credentials for the token to be valid.

I'm not 100% sure that setting the token on the security.context is necessary if you are just going to redirect right away. But it doesn't seem to hurt so I have left it.

Then the important part, setting the session variable. The variables naming convention is _security_ followed by your firewall name, in this case main making _security_main.


Figured this one out, finally.

After user registration, you should have access to an object instanceof whatever you've set as your user entity in your provider configuration. The solution is to create a new token with that user entity and pass it into the security context. Here's an example based on my setup:

RegistrationController.php:

$token = new UsernamePasswordToken($userEntity, null, 'main', array('ROLE_USER'));$this->get('security.context')->setToken($token);

Where main is the name of the firewall for your application (thanks, @Joe). That's really all there is to it; the system now considers your user fully logged in as the user they've just created.

EDIT: Per @Miquel's comment, I've updated the controller code sample to include a sensible default role for a new user (though obviously this can be adjusted according to your application's specific needs).


If you have a UserInterface object (and that should be the case most of the time) you might want to use the getRoles function that it implements for the last argument.So if you create a function logUser, it should looks like that:

public function logUser(UserInterface $user) {    $token = new UsernamePasswordToken($user, null, 'main', $user->getRoles());    $this->container->get('security.context')->setToken($token);}