skip to Main Content

Using Symfony 7.1, while trying to implement user registration, I am getting this error:

An exception has been thrown during the rendering of a template ("Unable to generate a URL for the named route "login_check" as such route does not exist.").

I was under the assumption that this route is automatically generated by Symfony, yet checking the route, I don’t see it:

 php ./bin/console debug:router
 ------------------------------ ---------- -------- ------ ----------------------------------- 
  Name                           Method     Scheme   Host   Path                               
 ------------------------------ ---------- -------- ------ ----------------------------------- 
  _preview_error                 ANY        ANY      ANY    /_error/{code}.{_format}           
  _wdt                           ANY        ANY      ANY    /_wdt/{token}                      
  _profiler_home                 ANY        ANY      ANY    /_profiler/                        
  _profiler_search               ANY        ANY      ANY    /_profiler/search                  
  _profiler_search_bar           ANY        ANY      ANY    /_profiler/search_bar              
  _profiler_phpinfo              ANY        ANY      ANY    /_profiler/phpinfo                 
  _profiler_xdebug               ANY        ANY      ANY    /_profiler/xdebug                  
  _profiler_font                 ANY        ANY      ANY    /_profiler/font/{fontName}.woff2   
  _profiler_search_results       ANY        ANY      ANY    /_profiler/{token}/search/results  
  _profiler_open_file            ANY        ANY      ANY    /_profiler/open                    
  _profiler                      ANY        ANY      ANY    /_profiler/{token}                 
  _profiler_router               ANY        ANY      ANY    /_profiler/{token}/router          
  _profiler_exception            ANY        ANY      ANY    /_profiler/{token}/exception       
  _profiler_exception_css        ANY        ANY      ANY    /_profiler/{token}/exception.css   
  event_list                     GET        ANY      ANY    /events/list                       
  app_helloworld_sayhelloworld   ANY        ANY      ANY    /
  app_helloworld_sayok           ANY        ANY      ANY    /status
  app_register                   ANY        ANY      ANY    /register
  app_login                      ANY        ANY      ANY    /login                             
  app_logout                     ANY        ANY      ANY    /logout
  user_index                     GET        ANY      ANY    /user/
  user_new                       GET|POST   ANY      ANY    /user/new
  user_show                      GET        ANY      ANY    /user/{id}
  user_edit                      GET|POST   ANY      ANY    /user/{id}/edit
  user_delete                    POST       ANY      ANY    /user/{id}

This is my security.yaml:

security:
    providers:
        users:
            entity:
                class: 'AppEntityUser'
                property: 'email'


    # https://symfony.com/doc/current/security.html#registering-the-user-hashing-passwords
    password_hashers:
        AppEntityUser:
            algorithm: bcrypt
            cost: 12

    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
        main:
#            pattern: ^/
            lazy: true
            provider: users
            form_login:
                login_path: app_login
                check_path: login_check
                default_target_path: event_list
                username_parameter: _email
                password_parameter: _password
            logout:
                path: app_logout
            entry_point: AppSecurityEntryPoint
            # activate different ways to authenticate
            # https://symfony.com/doc/current/security.html#the-firewall

            # https://symfony.com/doc/current/security/impersonating_user.html
            # switch_user: true

    # Easy way to control access for large sections of your site
    # Note: Only the *first* access control that matches will be used
    access_control:
        - { path: ^/login, roles: PUBLIC_ACCESS  }
        - { path: ^/events, roles: IS_AUTHENTICATED_FULLY }
        - { path: ^/admin, roles: ROLE_ADMIN }

when@test:
    security:
        password_hashers:
            # By default, password hashers are resource intensive and take time. This is
            # important to generate secure password hashes. In tests however, secure hashes
            # are not important, waste resources and increase test times. The following
            # reduces the work factor to the lowest possible values.
            SymfonyComponentSecurityCoreUserPasswordAuthenticatedUserInterface:
                algorithm: auto
                cost: 4 # Lowest possible value for bcrypt
                time_cost: 3 # Lowest possible value for argon
                memory_cost: 10 # Lowest possible value for argon

2

Answers


  1. Chosen as BEST ANSWER

    I figured how to manually provide the route:

    In my ./config/routes.yaml, I added:

    login_check:
        path: /login_check
        controller: SymfonyComponentSecurityHttpAuthenticationLoginCheckAuthenticator
        methods: [POST]
    
    And in my SecurityController, I added:
    
    
    #[Route('/login_check', name: 'login_check', methods: ['POST'])]
    public function loginCheck(): Response {
        // Symfony handles this route internally
        return new Response('Login check route');
    }
    
    
    Now the `check_path` seems to work.
    

  2. Your setting on security.firewalls.main.form_login.check_path is telling Symfony to find one specific route. That route doesn’t exist, so logically complains that it cannot generate it.

    This setting just tells Symfony to intercept any POST requests to this URL. As such, the controller action associated with this route, when executing a POST request, is never executed, and having a controller for it would be redundant.

    It’s unnecessary to create a custom route just to handle this. The recommended way of going about this is the one suggested on the docs: set the check_path to the same value as login_path.

    This way, a GET request to login_path will render the login form, and a POST request to the same URL will be intercepted by the Symfony Security component, to check the user’s credentials:

    # config/packages/security.yaml
    security:
        # ...
    
        firewalls:
            main:
                # ...
                form_login:
                    # "app_login" is the name of the route created previously
                    login_path: app_login
                    check_path: app_login
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search