Blog IT

Last night I was experimenting with Silex and I needed a register/login form. Silex comes with a SecurityServiceProvider which gives you the power of the symfony/security component. But I couldn’t figure out how to programmatically login the user after registration. So here’s my solution:

In order to login you have to do following steps

  1. get user from database
  2. generate token
  3. update security context
  4. dispatch login event
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use  Symfony\Component\Security\Http\Event\InteractiveLoginEvent;

class SomeController extends Controller
{
    public function someAction()
   {
        // get user from database
        $user = $this->get('doctrine')->getRepository('SomeUserBundle:User')->findOneByUsername($username);
        // Here, "public" is the name of the firewall in your security.yml
        $token = new UsernamePasswordToken($user, $user->getPassword(), "public", $user->getRoles());
        $this->get("security.context")->setToken($token);

        // Fire the login event
        // Logging the user in above the way we do it doesn't do this automatically
        $event = new InteractiveLoginEvent($request, $token);
        $this->get("event_dispatcher")->dispatch("security.interactive_login", $event);
   }
}

How to in Tests using HWIOAuthBundle

If you use HWIOAuthBundle and want to programmatically login/authenticate a user then you can use following code. First of all, let's create a base class for our tests and then extend each test class from this one. To simulate login call parent class method "login" in any function.

use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Symfony\Component\BrowserKit\Cookie;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use HWI\Bundle\OAuthBundle\Security\Core\Authentication\Token\OAuthToken;
use HWI\Bundle\OAuthBundle\Security\Core\User\OAuthUser;
/**
 *
 * This class is used to login to the system an test user's feature.
 *
 */
abstract class BaseCredentialsTest extends WebTestCase
{
    /**
     *
     * @var \Symfony\Bundle\FrameworkBundle\Client
     */
    protected $client = null;

    /**
     *
     */
    public function setUp()
    {
        $this->client->insulate();
    }


    protected function logIn()
    {
        $token = new OAuthToken('test', array( 'ROLE_MODERATOR'));

        // get user from doctrine
        $username = 'someusername';
        $user = $this->client->getContainer()->get('doctrine')->getRepository('SomeUserBundle:User')->findOneByUsername($username);

        //
        $token->setUser($user);
        $session = $this->client->getContainer()->get('session');
        $session->set('_security_public', serialize($token));
        $session->save();
        $cookie = new Cookie($session->getName(), $session->getId());
        $this->client->getCookieJar()->set($cookie);
    }
}