We're building a business app from the ground up in Symfony 2, and I've run into a bit of a snag with the user registration flow: after the user creates an account, they should be automatically logged in with those credentials, instead of being immediately forced to provide their credentials again.
Anyone had any experience with this, or able to point me in the right direction?
Symfony 4.0
This process hasnt 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 dont 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.yml
security:
firewalls:
main:
//firewall settings here
And a controller action similar too:
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 dont need to provide the user credentials for the token to be valid.
Im not 100% sure that setting the token on the security.context
is necessary if you are just going to redirect right away. But it doesnt 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