如何以编程方式login/authentication用户?

我想在注册过程之后立即login用户,而不通过login表单。

这可能吗 ? 我已经find了FOSUserBundle的解决scheme,但是我并没有将它用于实际工作的项目。

这里是我的security.yml,我正在使用两个防火墙。 纯文本编码器仅用于testing。

 security: encoders: Symfony\Component\Security\Core\User\User: plaintext Ray\CentralBundle\Entity\Client: md5 role_hierarchy: ROLE_ADMIN: ROLE_USER ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH] providers: in_memory: users: admin: { password: admin, roles: [ 'ROLE_ADMIN' ] } entity: entity: { class: Ray\CentralBundle\Entity\Client, property: email } firewalls: dev: pattern: ^/(_(profiler|wdt)|css|images|js)/ security: false user_login: pattern: ^/user/login$ anonymous: ~ admin_login: pattern: ^/admin/login$ anonymous: ~ admin: pattern: ^/admin provider: in_memory form_login: check_path: /admin/login/process login_path: /admin/login default_target_path: /admin/dashboard logout: path: /admin/logout target: / site: pattern: ^/ provider: entity anonymous: ~ form_login: check_path: /user/login/process login_path: /user/login default_target_path: /user logout: path: /user/logout target: / access_control: - { path: ^/user/login, roles: IS_AUTHENTICATED_ANONYMOUSLY } - { path: ^/admin/login, roles: IS_AUTHENTICATED_ANONYMOUSLY } - { path: ^/user, roles: ROLE_USER } - { path: ^/admin, roles: ROLE_ADMIN } - { path: ^/, roles: IS_AUTHENTICATED_ANONYMOUSLY } 

是的,你可以通过类似于以下内容的方式来做到这一点:

 use Symfony\Component\EventDispatcher\EventDispatcher, Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken, Symfony\Component\Security\Http\Event\InteractiveLoginEvent; public function registerAction() { // ... if ($this->get("request")->getMethod() == "POST") { // ... Do any password setting here etc $em->persist($user); $em->flush(); // Here, "public" is the name of the firewall in your security.yml $token = new UsernamePasswordToken($user, $user->getPassword(), "public", $user->getRoles()); // For older versions of Symfony, use security.context here $this->get("security.token_storage")->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); // maybe redirect out here } } 

当你在上下文中设置一个标记时,事件触发事件不会自动完成,而通常在使用login表单或类似的事件时。 因此,在这里包括它的原因。 您可能需要调整使用的令牌types,具体取决于您的使用情况 – 上面显示的UsernamePasswordToken是核心令牌,但您可以根据需要使用其他令牌。

编辑 :调整上述代码来解释“公共”参数,并根据下面的佛朗哥的评论添加用户angular色的令牌创build。

接受的版本不会与symfony 3.3一起使用。 用户将在下一个请求中进行身份validation,而不是当前的身份validation。 原因是ContextListener检查以前的会话是否存在,如果不存在则清除安全TokenStorage。 唯一的解决办法就是通过手动初始化当前请求的会话(和cookie)来伪造前一会话的存在。

让我知道如果你find一个更好的解决scheme。

顺便说一句,我不知道这是否应该与公认的解决scheme合并。

 private function logUserIn(User $user) { $token = new UsernamePasswordToken($user, null, "common", $user->getRoles()); $request = $this->requestStack->getMasterRequest(); if (!$request->hasPreviousSession()) { $request->setSession($this->session); $request->getSession()->start(); $request->cookies->set($request->getSession()->getName(), $request->getSession()->getId()); } $this->tokenStorage->setToken($token); $this->session->set('_security_common', serialize($token)); $event = new InteractiveLoginEvent($this->requestStack->getMasterRequest(), $token); $this->eventDispatcher->dispatch("security.interactive_login", $event); } 

上面的代码假定您的防火墙名称(或共享上下文名称)是common

试试这个: 对于Symfony 3用户 ,不要忘记进行这个更正来testing密码是否相等(因为testing这个链接上的密码的方法不起作用):

 $current_password = $user->getPassword(); $user_entry_password = '_got_from_a_form'; $factory = $this->get('security.encoder_factory'); $encoder = $factory->getEncoder($user); $password = $encoder->encodePassword($user_entry_password, $user->getSalt()); if(hash_equals($current_password, $password)){ //Continue there } // I hash the equality process for more security 

+ info: hash_equals_function