Как аутентифицировать (войти) вручную пользователя в контроллере (с или без FOSUserBundle) в Symfony 3

Такие инструменты, как FOSUserBundle, упрощают работу, когда мы говорим о манипулировании пользователями, формах входа и регистрации и т. Д. Кто не может сказать «нет»? Наверное, те, кому нужно все контролировать и понимать, как это работает. Вот почему некоторые разработчики, даже если они не используют FOSUserBundle, предпочитают обрабатывать эти события вручную.

Ищете логин вашего пользователя с собственным кодом из контроллера? Вы нашли правильное место, чтобы изучить его. В этой статье вы узнаете, как автоматически войти в систему в приложении Symfony (с учетными данными или без них).

Как это сделать

Первое, что вам нужно сделать, это импортировать некоторые классы, а именно InteractiveLoginEvent а также UsernamePasswordToken в вашем контроллере. Затем найдите своего пользователя, используя менеджер сущностей Doctrine, или, в качестве альтернативы, используйте менеджер пользователей FOSUserBundle. Пользователь должен храниться в переменной и будет представлять собой экземпляр FOS\UserBundle\Model\User в случае, если вы используете FOSUser или просто пользователя, если вы этого не сделаете. Далее необходимо создать токен и установить его в службу хранения токенов. Класс для создания токена ожидает в качестве первого аргумента пользовательский объект, а вторым аргументом обычно является пароль пользователя, однако он может быть нулевым. В качестве третьего аргумента необходимо указать имя используемого брандмауэра, обычно main Однако стоит проверить ваши security.yml файл на случай, если у него есть другое имя. В качестве четвертого аргумента вам необходимо указать роли пользователя.

Вам также необходимо сохранить токен, сгенерированный классом, в сеансе и, наконец, отправить событие интерактивного входа вручную:

getDoctrine()->getManager()->getRepository("AppBundle/Entity/User")->findOneBy(array('username' => "some user name example"));
//Handle getting or creating the user entity likely with a posted form
// The third parameter "main" can change according to the name of your firewall in security.yml
$token = new UsernamePasswordToken($user, null, 'main', $user->getRoles());
$this->get('security.token_storage')->setToken($token);
// If the firewall name is not main, then the set value would be instead:
// $this->get('session')->set('_security_XXXFIREWALLNAMEXXX', serialize($token));
$this->get('session')->set('_security_main', serialize($token));
// Fire the login event manually
$event = new InteractiveLoginEvent($request, $token);
$this->get("event_dispatcher")->dispatch("security.interactive_login", $event);
/*
* Now the user is authenticated !!!!
* Do what you need to do now, like render a view, redirect to route etc.
*/
}
}

Сделав это, вы автоматически зарегистрировали пользователя в сеансе, однако вы не проверили учетные данные пользователя.

Пример нестандартного контроллера входа

Предположим, что вы создаете некоторую настраиваемую форму входа (или переопределяете форму входа по умолчанию для FOSUserBundle), и вам нужно аутентифицировать пользователя вручную. Для этого первый пример контроллера будет работать только для установки пользователя в сеансе, однако на самом деле он не аутентифицируется, поскольку мы не проверяем ни имя пользователя, ни пароль.

Первое, что нам нужно сделать перед настройкой пользователя в сеансе, это проверить правильность предоставленных им учетных данных. Для этого нам понадобится служба безопасного кодирования в нашем контроллере, чтобы проверить подлинность предоставленных данных. В этом примере мы собираемся показать вам с базовой логикой, как работает процесс аутентификации:

get('security.encoder_factory');
/// Start retrieve user
// Let's retrieve the user by its username:
// If you are using FOSUserBundle:
$user_manager = $this->get('fos_user.user_manager');
$user = $user_manager->findUserByUsername($_username);
// Or by yourself
$user = $this->getDoctrine()->getManager()->getRepository("userBundle:User")
->findOneBy(array('username' => $_username));
/// End Retrieve user
// Check if the user exists !
if(!$user){
return new Response(
'Username doesnt exists',
Response::HTTP_UNAUTHORIZED,
array('Content-type' => 'application/json')
);
}
/// Start verification
$encoder = $factory->getEncoder($user);
$salt = $user->getSalt();
if(!$encoder->isPasswordValid($user->getPassword(), $_password, $salt)) {
return new Response(
'Username or Password not valid.',
Response::HTTP_UNAUTHORIZED,
array('Content-type' => 'application/json')
);
}
/// End Verification
// The password matches ! then proceed to set the user in session
//Handle getting or creating the user entity likely with a posted form
// The third parameter "main" can change according to the name of your firewall in security.yml
$token = new UsernamePasswordToken($user, null, 'main', $user->getRoles());
$this->get('security.token_storage')->setToken($token);
// If the firewall name is not main, then the set value would be instead:
// $this->get('session')->set('_security_XXXFIREWALLNAMEXXX', serialize($token));
$this->get('session')->set('_security_main', serialize($token));
// Fire the login event manually
$event = new InteractiveLoginEvent($request, $token);
$this->get("event_dispatcher")->dispatch("security.interactive_login", $event);
/*
* Now the user is authenticated !!!!
* Do what you need to do now, like render a view, redirect to route etc.
*/
return new Response(
'Welcome '. $user->getUsername(),
Response::HTTP_OK,
array('Content-type' => 'application/json')
);
}
}
Ссылка на основную публикацию
Adblock
detector