3
votes

I'm having a problem with FOSUserBundle since any time I login with bad credentials I get the complete stacktrace as error message:

Error! exception 'Symfony\Component\Security\Core\Exception\BadCredentialsException' with message 'Bad credentials' in /var/www/html/vendor/symfony/symfony/src/Symfony/Component/Security/Core/Authentication/Provider/UserAuthenticationProvider.php:90

And that is ugly for me so for users is very ugly. So I'm thinking in two solutions: change to AJAX login which I'm working on but it's not working or I'm doing something wrong (will explain below) and found a way to change that ugly message (I didn't get this one yet so any advice will be helpful).

Now regarding the first solution this is what I have done:

  • Implements a AuthenticationHandler:

    <?php
    
    namespace UsuarioBundle\Handler;
    
    use Symfony\Component\HttpFoundation\Response;
    use Symfony\Component\HttpFoundation\RedirectResponse;
    use Symfony\Bundle\FrameworkBundle\Routing\Router;
    use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
    use Symfony\Component\HttpFoundation\Request;
    use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface;
    use Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface;
    use Symfony\Component\Security\Core\Exception\AuthenticationException;
    
    class AuthenticationHandler
        implements AuthenticationSuccessHandlerInterface,
        AuthenticationFailureHandlerInterface
    {
        private $router;
    
        public function __construct(Router $router)
        {
            $this->router = $router;
        }
    
        public function onAuthenticationSuccess(Request $request, TokenInterface $token)
        {
            if ($request->isXmlHttpRequest()) {
                // do I need something here?
            } else {
                // If the user tried to access a protected resource and was forces to login
                // redirect him back to that resource
                if ($targetPath = $request->getSession()->get('_security.target_path')) {
                    $url = $targetPath;
                } else {
                    // Otherwise, redirect him to wherever you want
                    $url = $this->router->generate('user_view', array('nickname' => $token->getUser()->getNickname()));
                }
    
                return new RedirectResponse($url);
            }
        }
    
        public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
        {
            if ($request->isXmlHttpRequest()) {
                // Handle XHR here
            } else {
                // Create a flash message with the authentication error message
                $request->getSession()->setFlash('error', $exception->getMessage());
                $url = $this->router->generate('user_login');
    
                return new RedirectResponse($url);
            }
        }
    }
    
  • Define a service and register the handler:

    parameters:
        vendor_security.authentication_handler: UsuarioBundle\Handler\AuthenticationHandler
    
    services:
        authentication_handler:
            class:  %vendor_security.authentication_handler%
            arguments:  [@router]
            tags:
                - { name: 'monolog.logger', channel: 'security' }
    
  • Change the references in security.yml:

    firewalls: main: pattern: ^/ form_login: provider: fos_userbundle csrf_provider: form.csrf_provider login_path: /login check_path: /login_check success_handler: authentication_handler failure_handler: authentication_handler

          logout:
               path: fos_user_security_logout
               target: /
               invalidate_session: false
          anonymous: ~
    

But I get this error when I try to login with invalid credentials:

Attempted to call method "setFlash" on class "Symfony\Component\HttpFoundation\Session\Session" in /var/www/html/src/UsuarioBundle/Handler/AuthenticationHandler.php line 52.

Why? I check for getSession() method and it's part of HttpFoundation which I include in use statements, so what I'm doing wrong here?

Note: I take the code mostly from this topic so for that I'm still having some doubts around it.

1
I think you have to use session->getFlashBag()->add() instead of setFlash.Alex

1 Answers

9
votes

$request->getSession()->setFlash('error', 'error'); was a notation for "old" symfony version.

Now you should use

$reqest->getSession()->getFlashBag()->add('error', $exception->getMessage());

Moreover, are you sure that is a good practice to show $exception text message? I mean, I don't know in what page this flash will be shown BUT if a user, or even an admin - that of course doesn't knows pretty much anything about PHP and programming in general - can see tha page and so the message, you should try to log the message for your purpose BUT show something else to user.