简体   繁体   English

如何为FOSOAuthServerBundle覆盖TokenController?

[英]How to override TokenController for FOSOAuthServerBundle?

I followed Symfony's cookbook on how to override bundle controller, but for some reason I can't get it working. 我遵循了Symfony的食谱,了解如何覆盖捆绑控制器,但是由于某种原因,我无法使其正常运行。

My OAuth bundle is a child of FOSOAuthServerBundle . 我的OAuth捆绑包是FOSOAuthServerBundle的子FOSOAuthServerBundle My TokenController is declared as class TokenController extends \\FOS\\OAuthServerBundle\\Controller\\TokenController . 我的TokenController被声明为TokenController类扩展\\FOS\\OAuthServerBundle\\Controller\\TokenController But for some reason I still get parent controller executed, instead of my own controller (child). 但是由于某种原因,我仍然要执行父控制器,而不是自己的控制器(子控制器)。 When I alter routing manually to point /oauth/v2/token to my TokenController directly, I get it executing, but with an 500 error: 当我手动更改路由以将/oauth/v2/token直接指向我的TokenController ,我将其执行,但出现500错误:

Argument 1 passed to FOS\\OAuthServerBundle\\Controller\\TokenController::__construct() must be an instance of OAuth2\\OAuth2, none given, called in /.../vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Controller/ControllerResolver.php on line 78 and defined (500 Internal Server Error) 传递给FOS \\ OAuthServerBundle \\ Controller \\ TokenController :: __ construct()的参数1必须是OAuth2 \\ OAuth2的实例,没有给出,在/.../vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Controller中调用/ControllerResolver.php在第78行并已定义(500内部服务器错误)

Why? 为什么? I am puzzled. 我很困惑。 What's wrong? 怎么了? Any help will be appreciated. 任何帮助将不胜感激。 Thanks. 谢谢。

What Mick said is true. 米克说的是真的。 To follow up on 3 (overriding a service), read on. 要跟进3 (覆盖服务),请继续阅读。

In app/config/services.yml , add the following: app/config/services.yml ,添加以下内容:

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

Where OAuth2Bundle\\Controller\\TokenController is your custom controller extending the one from the FOS bundle. 其中OAuth2Bundle\\Controller\\TokenController是您的自定义控制器,是从FOS捆绑包中扩展OAuth2Bundle\\Controller\\TokenController

For example: 例如:

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;
    }
}

Of course, you can do whatever you like with $result . 当然,您可以使用$result做任何您想做的事情。 You can even omit the parent:: call and perform your own authentication to return a token. 您甚至可以省略parent::并执行自己的身份验证以返回令牌。

EDIT 编辑

This is a follow up on the above. 这是上面的后续内容。 I had to access some entities and do some updates when a user would receive a token. 当用户收到令牌时,我必须访问一些实体并进行一些更新。 This required me to have access to the entity manager. 这要求我有权访问实体管理器。 In my case I had to check if the OAuth client is still active; 就我而言,我必须检查OAuth客户端是否仍处于活动状态; it isn't deleted, but just temporarily disabled to block a group of users. 它不会被删除,只是暂时被禁用以阻止一组用户。

Because the controller is a service, you can add extra parameters like the entity manager: 由于控制器是一项服务,因此您可以添加其他参数,例如实体管理器:

The service definition now looks like this: 现在,服务定义如下所示:

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

And of course the controller now has a constructor. 当然,控制器现在具有构造函数。 It now looks like this: 现在看起来像这样:

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;
    }
}

A few thoughts: 一些想法:

1 Did you declare your bundle in AppKernel.php ? 1您是否在AppKernel.php声明了包?

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

2 As you can see in oauth.xml and in the Controller class , the controller expects the server OAuth2 in its constructor. 2如在oauth.xmlController类所见 ,控制器期望服务器OAuth2在其构造函数中。 So if you override the constructor, make sure to include 'use OAuth2\\OAuth2;' 因此,如果您覆盖了构造函数,请确保包含“ use OAuth2 \\ OAuth2;” at the top of your file. 在文件的顶部。

3 Since the controller is used as a service, you might have to override oauth.xml to redefine the class to use for that service. 3由于控制器用作服务,因此您可能必须重写oauth.xml以重新定义用于该服务的类。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM