2017-08-30 9 views
0

symfony3で私の最初のAPIログインをビルドしていますが、ログインリスナーにトリップしました。私は、ユーザーがログの書き込み、トークンの生成など、さまざまな通常の目的のために正常にログインした時点でイベントを発生させたいと考えています。 ログインシステムはAPIを介して行われているため、 symfonyガイドに記載されている古典的なログインフォーム。この光で、私は逃した何かがあると確信しています。ログイン後にsymfony 3リスナーが実行されない

リスナーの初期化:

// 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');です。検証は、ユーザーとパスワードが有効で、ログインが発生したときに、リスナーは考慮されないのはなぜサービス(それはthisにかなり似ている方法loadUserByUsernameAndPassword、)、

としてインスタンス化カスタムユーザプロバイダクラスで行われていますinteractive_loginイベントを発動させる有効なイベントですか?

+0

このプロジェクトではセキュリティコンポーネントが使用されていないようです:) –

+0

実際にどこにログインしているのかわかりません。たとえば、トークン・ストレージが更新される場所はどこですか? – Cerad

+0

@ MaxP。私はsecurity.ymlで投稿を更新しました。 –

答えて

2

何らかの理由であなたが本当に手動で、ユーザーがログインし、適切な時間に自分のコントローラとのコールに、このメソッドを追加する必要がある場合:(

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)がこれを行います。

+0

ありがとうございました。これは正常に動作します。 しかし、私はガードを見てみましょう、私は一見で私にはそれほど明確ではなかったので、これを選びました、そしてそれはちょっと頭をはめたものです。 これに関するちょっと疑問ですが、変数 '$ token'が空の文字列を返すのはなぜですか? –

+0

トークン情報はセッションに格納されます。それは、アプリケーションが要求の間に誰がログインしたのかを記憶することを可能にするものです。空の文字列を返すことがどういう意味か分かりません。 – Cerad

+0

ええ、十分に公正です。私はポイントを得た。最後に私はそれをguarddで開発しました。期待したほうが簡単だった。幸いなことに、この投稿は私を助けてくれました。https://stackoverflow.com/questions/34250444/symfony-2-guard-component-and-normal-login-form –

関連する問題