Search code examples
phpsymfonysecurityauthenticationsymfony-3.4

Controller "SecurityController::loginAction()" requires that you provide a value for the "$authenticationUtils" argument


I am trying to set up a login form since removing the fos user bundle from my project (symfony3.4)

My problem is with the loginAction that it requires AuthenticationUtils but it receives null.

I tried linking it in my services.yml but it will not budge.

Any help will be greatly appreciated.

Here the following files [SecurityController.php, services.yml, routing.tml]

SecurityController.php

<?php

 namespace AppBundle\Controller;
 
 use Symfony\Bundle\FrameworkBundle\Controller\Controller;
 use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
 
 class SecurityController extends Controller
 {
     public function loginAction(AuthenticationUtils $authenticationUtils)
     {
         // get the login error if there is one
         $error = $authenticationUtils->getLastAuthenticationError();

         // last username entered by the user
         $lastUsername = $authenticationUtils->getLastUsername();

         return $this->render('security/login.html.twig', [
             'last_username' => $lastUsername,
             'error'         => $error,
         ]);
     }
 }

routing.yml

login:
  path: /{_locale}/login
  defaults: { _controller: 'AppBundle:Security:login' }
  requirements:
    _locale: "%languages%"

services.yml

services:      
    AppBundle\Controller\SecurityController:
        class:  'AppBundle\Controller\SecurityController'
        arguments: ['@security.authentication_utils']

hopefully anyone has an idea because i have been stuck for a few days now.

Thanks in advance


Solution

  • If you would use autowiring, this was easier (as you would not need any complex configuration to use services in actions) - but let's see why this currently does not work.

    Through your service configuration, you provide arguments for the constructor of AppBundle\Controller\SecurityController. That class does not contain any constructor in the current state, so the class does not contain any reference to the AuthenticationUtils service.

    If you don't want to use autowiring, this would help: add a constructor to your controller class, and Symfony's container will inject the service

    class SecurityController extends Controller
     {
         private $authenticationUtils;
    
         public function __construct(AuthenticationUtils $authenticationUtils) {
             $this->authenticationUtils = $authenticationUtils;
         }
    
         public function loginAction()
         {
             // get the login error if there is one
             $error = $this-authenticationUtils->getLastAuthenticationError();
    
             // last username entered by the user
             $lastUsername = $this-authenticationUtils->getLastUsername();
    
             return $this->render('security/login.html.twig', [
                 'last_username' => $lastUsername,
                 'error'         => $error,
             ]);
         }
     }