简体   繁体   English

使用FOSOAuthServerBundle在postPersist上生成令牌

[英]Generate Token on postPersist with FOSOAuthServerBundle

I'm trying to create a token on registration. 我正在尝试在注册时创建令牌。 I use FosUserBundle as authenticator and FOSOAuthServerBundle for API. 我将FosUserBundle用作身份验证器,并将FOSOAuthServerBundle用于API。

Everything works well when i generate a token manually. 当我手动生成令牌时,一切正常。 But i want to generate it automatically after a successful registration. 但是我想在成功注册后自动生成它。 So i created a EventListener called TokenSetter 所以我创建了一个名为TokenSetterEventListener

Here is the code 这是代码

class TokenSetter
{
protected $container;

public function __construct(ContainerInterface $container)
{
    $this->container = $container;
}

public function postPersist(LifecycleEventArgs $args)
{
    $user = $args->getEntity();

    if ($user instanceof Account) {
        $clientManager = $this->container->get('fos_oauth_server.client_manager.default');
        $client = $clientManager->createClient();
        $client->setRedirectUris(array('http://127.0.0.1:8000'));
        $client->setAllowedGrantTypes(array('password', 'refresh_token'));
        $clientManager->updateClient($client);

        $grantRequest = new Request(array(
            'client_id'  => $client->getPublicId(),
            'client_secret' => $client->getSecret(),
            'grant_type' => 'password',
            'username' => $user->getUsername(),
            'password' => $user->getPlainPassword()
        ));

        $tokenResponse = $this->container->get('fos_oauth_server.server')->grantAccessToken($grantRequest);

        $token = $tokenResponse->getContent();
    }
}
}

The issue is that the $user->getPlainPassword() returns a empty value. 问题是$user->getPlainPassword()返回一个空值。 This results in a "invalid_request" after creation. 创建后将导致“ invalid_request”。

Is there a way to get the plain password or generate the token a different way? 有没有办法获得普通密码或以其他方式生成令牌?

Solved it myself. 我自己解决了。

There are two ways to solve this. 有两种解决方法。

First method is to change password to client_credentials . 第一种方法是将password更改为client_credentials This way you do not need to send a username and password when generating a access token. 这样,您在生成访问令牌时无需发送用户名和密码。 The down side is that the value of the user_id will be set to NULL . user_iduser_id的值将设置为NULL

Second solution is to create a different listener. 第二种解决方案是创建一个不同的侦听器。 (RegistrationListener)

You need to edit the UserEntity and add a TempPlainPass getter and setter. 您需要编辑UserEntity并添加TempPlainPass getter和setter。 Basically what you need to do is, storing the plainpassword in the database onRegistrationSuccess and create a token with username and password on onRegistrationCompleted 基本上你需要做的是,存储在数据库中的plainpassword什么onRegistrationSuccess并创建一个令牌上的用户名和密码onRegistrationCompleted

IMPORTANT! 重要! Don't forget to delete the TempPlainPass after generating a token 生成令牌后,别忘了删除TempPlainPass

See the code below: 请参见下面的代码:

class RegistrationListener implements EventSubscriberInterface
{
protected $container;

public function __construct(ContainerInterface $container)
{
    $this->container = $container;
}


public static function getSubscribedEvents()
{
    return array(
        FOSUserEvents::REGISTRATION_SUCCESS => 'onRegistrationSuccess',
        FOSUserEvents::REGISTRATION_COMPLETED => 'onRegistrationCompleted',
    );
}

public function onRegistrationSuccess(FormEvent $event)
{
    $user = $event->getForm()->getData();
    $user->setTempPlainPass($user->getPlainPassword());
    $user->setRoles(array('ROLE_ADMIN'));
}

public function onRegistrationCompleted(FilterUserResponseEvent $event)
{
    $user = $event->getUser();
    $clientManager = $this->container->get('fos_oauth_server.client_manager.default');
        $client = $clientManager->createClient();
        $client->setRedirectUris(array('http://127.0.0.1:8000'));
        $client->setAllowedGrantTypes(array('password', 'refresh_token'));
        $clientManager->updateClient($client);

        $grantRequest = new Request(array(
            'client_id'  => $client->getPublicId(),
            'client_secret' => $client->getSecret(),
            'grant_type' => 'password',
            'username' => $user->getUsername(),
            'password' => $user->getTempPlainPass()
        ));

        $this->container->get('fos_oauth_server.server')->grantAccessToken($grantRequest);

        $em = $this->container->get('doctrine.orm.default_entity_manager');
        $update = $em->getRepository(Account::class)->findOneById($user->getId());
        $update->setTempPlainPass('');
        $em->flush();
}
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM