Я создаю свой первый вход в API с помощью Symfony3, но я подключился к прослушивателю входа. Я хочу, чтобы событие было запущено, как только пользователь успешно вошел в систему для различных обычных целей, таких как запись журнала, создание токена и т. Д.
Поскольку все происходит через API, система входа немного отличается от классической формы входа, описанной в руководствах Symfony. В этом свете я уверен, что что-то упустил.
Инициализация слушателя:
// config/services.yml
//...
login_listener:
class: 'User\LoginBundle\Listener\LoginListener'
tags:
- { name: 'kernel.event_listener', event: 'security.interactive_login', method: onSecurityInteractiveLogin }
Мой слушатель:
// User/LoginBundle/Listener/LoginListener.php
namespace User\LoginBundle\Listener;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
class LoginListener
{
public function onSecurityInteractiveLogin(InteractiveLoginEvent $event)
{
echo 'Hello, I am the login listener!!';
}
}
мой класс контроллеров
// User/LoginBundle/Controller/LoginController.php
//...
public function checkCredentialsAction(Request $request)
{
$recursiveValidator = $this->get('validator');
$user = new User;
$user->setUsername($request->request->get('username'));
$user->setPassword($request->request->get('password'));$errors = $recursiveValidator->validate($user);
if (count($errors) > 0) {
$errorsString = (string) $errors;
return new JsonResponse($errorsString);
}
$loginService = $this->get('webserviceUserProvider.service');
$user = $loginService->loadUserByUsernameAndPassword(
$request->get('username'),
$request->get('password')
);
if ($user instanceof WebserviceUser) {
return new JsonResponse('all right');
}
return new JsonResponse('Username / password is not valid', 403);
}
Мой компонент безопасности
security:
# https://symfony.com/doc/current/security.html#b-configuring-how-users-are-loaded
providers:
in_memory:
memory: ~
api_key_user_provider:
id: AppBundle\Security\ApiKeyUserProvider
# property: apiKey
user_db_provider:
entity:
class: UserUserBundle:User
# property: username
webservice:
id: User\UserBundle\Security\User\WebserviceUserProvider
encoders:
User\UserBundle\Entity\User:
algorithm: bcrypt
firewalls:
# disables authentication for assets and the profiler, adapt it according to your needs
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
user_logged:
pattern: ^/logged
stateless: true
simple_preauth:
authenticator: AppBundle\Security\ApiKeyAuthenticator
provider: api_key_user_provider
main:
anonymous: ~
form_login:
check_path: login/checkaccess_control:
- { path: ^/login/check, roles: IS_AUTHENTICATED_ANONYMOUSLY }
Как вы можете видеть, проверка выполняется в отношении сущности, и когда имя пользователя и пароль верны, возвращается json return new JsonResponse('all right, you are logged in');
, Проверка выполняется в классе Custom User Provider, который создается как сервис (метод loadUserByUsernameAndPassword
что очень похоже на этот),
Почему, когда действительны имя пользователя и пароль, и происходит вход в систему, слушатель не учитывается как допустимое событие для запуска interactive_login
событие?
Если по какой-то причине вам действительно нужно вручную войти в систему, добавьте этот метод в свой контроллер и вызовите в соответствующее время:
private function loginUser(Request $request, UserInterface $user)
{
$token = new UsernamePasswordToken($user, null, 'main', $user->getRoles());
$this->get("security.token_storage")->setToken($token);
$event = new InteractiveLoginEvent($request, $token);
$this->get("event_dispatcher")->dispatch(SecurityEvents::INTERACTIVE_LOGIN, $event);
}
if ($user instanceof WebserviceUser) {
$this->loginUser($request,$user);
return new JsonResponse('all right');
}
Тем не менее, в большинстве случаев существующая система аутентификации (или пользовательский сторожевой аутентификатор, https://symfony.com/doc/current/security/guard_authentication.html) сделаю это для вас.
Других решений пока нет …