【问题标题】:Symfony 3.1: Unable to find the controller for path "/logout"Symfony 3.1:找不到路径“/logout”的控制器
【发布时间】:2016-11-18 12:31:13
【问题描述】:

我正在尝试使用 Symfony 3.1 完成我的注销功能,但到目前为止它还没有工作。我正在逐步遵循本书文档,但我得到的只是一个未找到的异常:

找不到路径“/logout”的控制器。路线错了 配置好了。

我确实在 security.yml 文件中激活了正确的配置参数(注销)

security:
       firewalls:
        # disables authentication for assets and the profiler, adapt it according to your needs
            dev:
                pattern: ^/(_(profiler|wdt)|css|images|js)/
                security: false

            main:
                anonymous: ~
                # activate different ways to authenticate
                form_login:
                    login_path: login
                    check_path: login
            secured_area:
                anonymous: ~
                logout:
                    path:   /logout
                    target: /

我确实在 routing.yml 中创建了一条路由:

logout:
    path: /logout

根据文档就是这样,不需要控制器,但异常表明控制器路径错误。

我做错了什么?

【问题讨论】:

    标签: php symfony logout


    【解决方案1】:

    我认为这是因为您定义了两个防火墙。目前,摆脱secured_area的东西并尝试类似:

    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
    
        main:
            pattern:  ^/
            anonymous: ~
            switch_user: true
    
            form_login:
                provider:            user_provider
                login_path:          user_login
                check_path:          user_login_check
                default_target_path: app_welcome
    
                username_parameter:  username
                password_parameter:  password
    
                csrf_parameter:       _csrf_token
                csrf_token_id:        authenticate
                csrf_token_generator: security.csrf.token_manager
    
            logout:
                path:   user_logout
                target: app_welcome
    

    请注意,注销部分位于主防火墙下。主防火墙工作后,如果确实需要,可以尝试重新添加secured_area。

    是的,我很懒惰,只是复制/粘贴了一个工作配置。您必须调整路线以匹配您的路线。

    【讨论】:

    • 经过一些更改(我删除了 csrf 的东西和提供者)它工作了!但是为什么在文档中使用安全区域?谢谢!
    • 我能理解这种困惑。配置安全组件可能具有挑战性。并且文档不是 100% 一致的。考虑为文档工作做出贡献:symfony.com/doc/current/contributing/documentation/…
    【解决方案2】:

    感谢您提供正确的最佳答案。还有一个技巧你应该注意: 确保 /logout 位于防火墙后面。 /logout 路径必须与防火墙模式匹配。

    例如:'pattern: ^/admin' 那么注销路径应该是 '/admin/logout'。

    【讨论】:

      【解决方案3】:

      如果您想使用两个防火墙,很可能您还需要两个登录表单和两个注销路由。

      添加连接路由很重要,在每个防火墙都可以识别的“模式”中断开连接

      路由配置:

      # config/routes.yaml
      logout_medical:
        path: /logout-medical
      
      logout_patient:
        path: /logout-patient
      
      # I omitted the declaration of the connection routes because they are made with annotations in the controllers
      

      防火墙配置:

      # config/packages/security.yaml
      security:
        # ...
      
        firewalls:
          # disables authentication for assets and the profiler, adapt it according to your needs
          dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
      
          main:
            pattern: ^/(logout-medical|login-medical|m)
            anonymous: ~
            provider: medical_provider
            form_login:
              login_path: login_medical
              check_path: login_medical
            logout:
              path: logout_medical
              target: login_medical
      
          patient_area:
            pattern: ^/(logout-patient|login-patient|p)
            anonymous: ~
            provider: patient_provider
            form_login:
              login_path: login_patient
              check_path: login_patient
            logout:
              path: logout_patient
              target: login_patient
      

      【讨论】:

        【解决方案4】:

        因为您很可能没有与该路由关联的控制器。 如果你使用像 FOSUser 这样的包,你只需要导入包提供的 routing.yml。如果您没有任何包/控制器来处理该路由,则必须实现一个。

        【讨论】:

        • 确实,我没有与该路由关联的控制器,因为食谱说不需要(控制器)。
        【解决方案5】:

        为 Cerad 的回答添加更多细节:Symfony 中的安全用户绑定到“安全上下文”,默认情况下,该上下文对应于防火墙。在您的情况下,您希望退出已施加 form_login 身份验证要求的上下文(“防火墙”),因此您的注销配置需要在“主”防火墙上设置,而不是在名为“安全区域”。

        文档使用防火墙名称“secured_area”只是为了表明此配置旨在用于保护您网站的一部分的防火墙。不打算将该名称逐字复制到您的配置中。相反,在您的情况下,您尝试保护的防火墙称为“主”。从这个意义上说,documentation 有点令人困惑,因为它在其他任何地方都只使用名为“main”的防火墙作为示例,包括设置安全区域的示例。所以我想在这个特定的例子中使用“main”可能会更好。

        此外,您需要确保注销路由(路径)实际上由您为其配置的防火墙处理,而不是被不同的防火墙“捕获”。在您的情况下,这将自动发生,因为您没有对“主”防火墙施加任何路径限制,因此它可以捕获所有内容。

        【讨论】:

          猜你喜欢
          • 2014-03-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-02-08
          • 2012-09-06
          • 2014-01-23
          相关资源
          最近更新 更多