Search code examples
symfonysymfony-4.4

return a custom status code in User Checker


I'm working with Symfony 4.4. I'm using JWT Authentication and I'm now creating a custom user checker: I want to return a custom response code and a custom message when user checker detect that user can not connect.

security.yaml:

    client_login:
        pattern:  ^/api/login
        provider: client_entity
        stateless: true
        anonymous: true
        json_login:
            check_path: api_login
            username_path: email
            success_handler:          lexik_jwt_authentication.handler.authentication_success
            failure_handler:          lexik_jwt_authentication.handler.authentication_failure
        user_checker: App\Security\UserChecker
    refresh:
        pattern:  ^/api/token/refresh
        stateless: true
        anonymous: true
    api:
        pattern:   ^/api
        stateless: true
        anonymous: true
        guard:
            authenticators:
                - App\Security\TokenAuthenticator
            provider: chain_providers #this provider will be ignored when getting the User
        user_checker: App\Security\UserChecker

UserChecker:

class UserChecker implements UserCheckerInterface
{
    public function checkPreAuth(UserInterface $user)
    {
        return;
    }

    public function checkPostAuth(UserInterface $user)
    {
        if (!$user instanceof Client) {
            return;
        }

        if (!$user->isActive()) {
            throw new AuthenticationException('userNotActive');
        }
    }
}

With this user checker the response when client is not active:

{
"code": 401,
"message": "An authentication exception occurred."
}

I want just to customize code and message.


Solution

  • If you only want to update response, you should create a listiner to handle failure authentification:

    <?php
    
    namespace App\EventListener;
    
    use App\Entity\User;
    use Lexik\Bundle\JWTAuthenticationBundle\Event\AuthenticationFailureEvent;
    
    /**
     * Authentication Failure Listener.
     *
     * This listener add data to payload.
     */
    class AuthenticationFailureListener
    {
        /**
         * When this event happened, response can be updated.
         *
         * @param AuthenticationFailureEvent $event the authentication Failure event
         */
        public function onAuthenticationFailureResponse(AuthenticationFailureEvent $event): void
        {
            $response = $event->getResponse();
    
            //TODO : edit your response here
            //dd($response);
    
            $event->setResponse($response);
        }
    }
    
    

    Declare the service in services.yaml file:

        App\EventListener\AuthenticationFailureListener:
            tags:
                - { name: kernel.event_listener, event: lexik_jwt_authentication.on_authentication_failure, method: onAuthenticationFailureResponse }