symfony 3.3 programmatically login a user with rem

2020-08-01 04:54发布

I want to login a user after registration successfully. Currently the solution I found online is login a user in a session basis. But I need the "remember me" feature. My research lead me to the

Symfony\Component\Security\Http\RememberMe\TokenBasedRememberMeServices

and its function

onLoginSuccess

But I'm out of luck and end up with circular reference detected for service. Also the onLoginSuccess is protected function. I assume I can duplicate those functions in my own function where performing a login feature. But that's always not a good choice. So I'd like to learn if anyone had experience on that?

1条回答
▲ chillily
2楼-- · 2020-08-01 05:27

Here I had my own answer. First, login user with following snippet

    $user = new \AppBundle\Security\User\EndUser($id, $userKey, $username, $password, $salt, $roles);
    $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));

Be aware that your own userProvider or EndUser maybe different from mine. Change the $user accordingly to make it work in your own situation.

Second, implement the remember me feature.

    $file   = sprintf("%s/config/security.yml", $this->container->getParameter('kernel.root_dir'));
    $parsed = Yaml::parse(file_get_contents($file));
    $options = $parsed['security']['firewalls']['main']['remember_me'];

    $endUserProvider = $this->container->get('AppBundle\Security\User\EndUserProvider');
    $secret = $providerKey = $this->container->getParameter('secret');
    $service = new TokenBasedRememberMeServices(array($endUserProvider), $secret, $providerKey, $options, null);
    $r = new \ReflectionMethod($service, 'onLoginSuccess');
    $r->setAccessible(true);
    $r->invoke($service, $request, $response, $token);

Some explanation here. Above code is firstly fetch remember me configuration for security.yml which is needed to initiate TokenBasedRememberMeServices instance. Then use the ReflectionMethod to overcome the accessible issue because method onLoginSuccess is originally protected.

This solution is tested under symfony 3.3.16. Hope this help others.

查看更多
登录 后发表回答