Symfony, nelmio/api-doc-bundle and @SWG\SecurityScheme

倾然丶 夕夏残阳落幕 提交于 2019-12-09 23:43:43

问题


I'm trying to document my Symfony 3.4 application API using nelmio/api-doc-bundle but fail to create a security scheme.

Generating the documentation itself works as expected with the following configuration:

nelmio_api_doc:
    documentation:
        info:
            description: FooBar API
            title: FooBar
            version: 1.0.0
    routes:
        path_patterns:
            - ^/api/

And the following annotations:

/**
 * @SWG\Get(
 *     security={
 *         {"ApiKeyAuth":{}}
 *     },
 *     @SWG\Response(
 *         response=200,
 *         description="Returns all [Foo]",
 *         @SWG\Schema(
 *             type="array",
 *             @Model(type=App\Entity\Foo::class)
 *         )
 *     ),
 *     @SWG\Response(
 *         response=404,
 *         description="Returns an error when no [Foo] were found"
 *     )
 * )
 */
public function cgetAction(): Response
{
    // ...
}

So I get a proper JSON file like this:

{
    "swagger" : "2.0",
    "info" : {
        "title" : "FooBar",
        "description" : "FooBar API",
        "version" : "1.0.0"
    },
    "paths" : {
        "\/api\/foo" : {
            "get" : {
                "responses" : {
                    "200" : {
                        "description" : "Returns all [Foo]",
                        "schema" : {
                            "items" : {
                                "$ref" : "#\/definitions\/Foo"
                            },
                            "type" : "array"
                        }
                    },
                    "404" : {
                        "description" : "Returns an error when no [Foo] were found"
                    }
                },
                "security" : [
                    {
                        "ApiKeyAuth" : [ ]
                    }
                ]
            }
        }
    },
    "definitions" : {
        "Foo" : {
            "properties" : {
                "id" : {
                    "type" : "integer"
                }
            },
            "type" : "object"
        }
    }
}

Now the problem is that I need to define ApiKeyAuthanywhere. Based on the examples I found ...

https://github.com/zircote/swagger-php/blob/master/Examples/petstore.swagger.io/controllers/StoreController.php

https://github.com/zircote/swagger-php/blob/master/Examples/petstore.swagger.io/security.php

https://swagger.io/docs/specification/2-0/authentication/api-keys/

... that might look like the following:

/**
 * @SWG\SecurityScheme(
 *     name="X-API-KEY",
 *     type="apiKey",
 *     in="header",
 *     securityDefinition="ApiKeyAuth"
 * )
 */

But regardless of where I put this in the controller it is not recognized.

So where is the right place for it?

Can I configure the api-doc-bundle to recognize a file with global definitions?

Do I need to create the definition in the config and not as annotation?

Does it work at all?


回答1:


A small change was required to make it work ...

/**
 * @SWG\Get(
 *     security={
 *         {"ApiKeyAuth":{}}
 *     },
 *     ...
 *     @SWG\Swagger(
 *         schemes={"https"},
 *         @SWG\SecurityScheme(
 *             name="X-API-KEY",
 *             type="apiKey",
 *             in="header",
 *             securityDefinition="ApiKeyAuth",
 *             description="API key"
 *         )
 *     )
 * )
 */
public function cgetAction(): Response
{
    // ...
}

Instead of adding the @SWG\SecurityScheme annotation at class level, or alongside @SWG\Get, placing it inside the request annotation block and wrapping it in a @SWG\Swagger block made the security definition show up.

Nevertheless, this was not sufficient as it involves a lot of duplication, and, moreover swagger-php fails with a duplicate definition error.

Thus I created a generic index controller which does nothing else but providing the security scheme annotation. Though this feels far from being the actual solution it solved the issue for now.

Here is the dummy controller:

<?php

namespace App\Controller\Api;

use FOS\RestBundle\Controller\Annotations\Route;
use FOS\RestBundle\Controller\FOSRestController;
use FOS\RestBundle\Routing\ClassResourceInterface;
use Swagger\Annotations as SWG;
use Symfony\Component\HttpFoundation\Response;

class IndexController extends FOSRestController implements ClassResourceInterface
{

    /**
     * @Route("/")
     * @SWG\Get(
     *     security={
     *         {"ApiKeyAuth":{}}
     *     },
     *     @SWG\Response(
     *         response=200,
     *         description="Returns 200 if the request was authorized",
     *     ),
     *     @SWG\Response(
     *         response=401,
     *         description="Returns 401 if the X-API-KEY header is missing or the provided token is not valid"
     *     ),
     *     @SWG\Swagger(
     *         schemes={"https"},
     *         @SWG\SecurityScheme(
     *             name="X-API-KEY",
     *             type="apiKey",
     *             in="header",
     *             securityDefinition="ApiKeyAuth",
     *             description="API key"
     *         )
     *     )
     * )
     */
    public function getAction(): Response
    {
        return $this->handleView($this->view(null, Response::HTTP_OK));
    }

}


来源:https://stackoverflow.com/questions/48143078/symfony-nelmio-api-doc-bundle-and-swg-securityscheme

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!