Слушатель Symfony 3 не запускается после входа в систему

Я создаю свой первый вход в 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/check


    access_control:
        - { path: ^/login/check, roles: IS_AUTHENTICATED_ANONYMOUSLY }

Как вы можете видеть, проверка выполняется в отношении сущности, и когда действителен пользователь / пароль, возвращается json: return new JsonResponse('all right, you are logged in');, Проверка выполняется в классе Custom User Provider, который создается как сервис (метод loadUserByUsernameAndPasswordчто очень похоже на это),

Почему, когда действительны имя пользователя и пароль, и происходит вход в систему, слушатель не учитывается как допустимое событие, чтобы запустить interactive_login событие?

1 ответ

Решение

Если по какой-то причине вам действительно нужно вручную войти в систему, добавьте этот метод в свой контроллер и вызовите в соответствующее время:

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) сделает это за вас.

Другие вопросы по тегам