【问题标题】:How to override TokenController for FOSOAuthServerBundle?如何覆盖 FOSOAuthServerBundle 的 TokenController?
【发布时间】:2014-01-29 03:43:44
【问题描述】:

我遵循了 Symfony 的关于如何覆盖捆绑控制器的食谱,但由于某种原因,我无法让它工作。

我的OAuth 捆绑包是FOSOAuthServerBundle 的子级。我的TokenController 被声明为类 TokenController 扩展\FOS\OAuthServerBundle\Controller\TokenController。但由于某种原因,我仍然执行父控制器,而不是我自己的控制器(子)。当我手动更改路由以将/oauth/v2/token 直接指向我的TokenController 时,我执行它,但出现500 错误:

传递给 FOS\OAuthServerBundle\Controller\TokenController::__construct() 的参数 1 必须是 OAuth2\OAuth2 的实例,没有给出,在 /.../vendor/symfony/symfony/src/Symfony/Bundle/ 中调用FrameworkBundle/Controller/ControllerResolver.php 在第 78 行并定义(500 Internal Server Error)

为什么?我很困惑。怎么了?任何帮助将不胜感激。谢谢。

【问题讨论】:

    标签: php symfony controller


    【解决方案1】:

    米克说的是真的。要跟进 3(覆盖服务),请继续阅读。

    app/config/services.yml 中,添加以下内容:

    services:
        fos_oauth_server.controller.token:
            class: OAuth2Bundle\Controller\TokenController
            arguments: [@fos_oauth_server.server]
    

    OAuth2Bundle\Controller\TokenController 是您的自定义控制器,它扩展了 FOS 捆绑包中的控制器。

    例如:

    namespace OAuth2Bundle\Controller;
    
    use FOS\OAuthServerBundle\Controller\TokenController as BaseController;
    use OAuth2\OAuth2;
    use Symfony\Component\HttpFoundation\Request;
    
    class TokenController extends BaseController {
    
        public function tokenAction(Request $request)
        {
            // Do whatever you like here
    
            $result = parent::tokenAction($request);
    
            // More custom code.
    
            return $result;
        }
    }
    

    当然,您可以使用$result 为所欲为。您甚至可以省略 parent:: 调用并执行您自己的身份验证以返回令牌。

    编辑

    这是对上述内容的跟进。当用户收到令牌时,我必须访问一些实体并进行一些更新。这要求我有权访问实体管理器。就我而言,我必须检查 OAuth 客户端是否仍然处于活动状态;它没有被删除,只是暂时禁用以阻止一组用户。

    因为控制器是一个服务,你可以像实体管理器一样添加额外的参数:

    服务定义现在如下所示:

    fos_oauth_server.controller.token:
      class: ApiBundle\Controller\OAuth\TokenController
      arguments: [@fos_oauth_server.server, @doctrine.orm.entity_manager]
    

    当然,控制器现在有了一个构造函数。现在看起来像这样:

    namespace OAuth2Bundle\Controller;
    
    use Doctrine\ORM\EntityManager;
    use FOS\OAuthServerBundle\Controller\TokenController as BaseController;
    use OAuth2\OAuth2;
    use Symfony\Component\HttpFoundation\Request;
    
    class TokenController extends BaseController {
    
        /**
         * @var EntityManager
         */
        private $em;
    
        /**
         * @param OAuth2 $server
         */
        public function __construct(OAuth2 $server, EntityManager $entityManager )
        {
            parent::__construct($server);
            $this->em = $entityManager;
        }
    
        public function tokenAction(Request $request)
        {
            // Do whatever you like here
    
            $result = parent::tokenAction($request);
    
            // More custom code.
    
            return $result;
        }
    }
    

    【讨论】:

    • 使用“编辑”部分:传递给 OAuthTokenController::__construct() 的参数 1 必须是 OAuth2\\OAuth2 的实例,没有给出,在 app/cache/dev/classes.php 中调用第 2214 行并定义”。传递的参数是 @fos_oauth_server.server。我不明白为什么没有给出。
    • 更新services.yml后是否清除缓存?该服务在此文件中定义:/vendor/friendsofsymfony/oauth-server-bundle/FOS/OAuthServerBundle/Resources/config/oauth.xml。它是 FOS 服务,所以它应该存在。
    【解决方案2】:

    一些想法:

    1 您是否在AppKernel.php 中声明了您的捆绑包?

    $bundles = array(
            ...
            new Acme\OAuthServerBundle()
        );
    

    2 正如您在oauth.xmlController class 中所见,控制器在其构造函数中期望服务器OAuth2。因此,如果您覆盖构造函数,请确保包含“使用 OAuth2\OAuth2;”在文件的顶部。

    3 由于控制器用作服务,您可能必须重写 oauth.xml 以重新定义用于该服务的类。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-06-27
    • 1970-01-01
    • 2021-06-26
    • 1970-01-01
    • 2015-09-09
    • 1970-01-01
    • 2012-12-17
    • 2020-07-28
    相关资源
    最近更新 更多