如何使用Swagger生成选项(CORS)

Rob*_*mel 6 c# swagger swashbuckle aws-api-gateway asp.net-core

对于我们正在开发的项目,我们会自动生成Swagger文件.但是此时我们正在努力应对CORS部分.

我们正在使用Amazon API网关导入api功能.要与Swagger和CORS结合使用,我们必须在源代码中创建一个额外的操作(操作),它允许每个api方法(操作)的CORS(选项)!例如:

    [HttpOptions]
    [Route("{id}")]
    [ProducesResponseType((int)HttpStatusCode.OK)]
    public IActionResult UserOptions()
    {
        return new OkResult();
    }
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,这会使代码变得更脏.这是一个临时修复,但我们找不到另一种方法.有没有办法在swagger定义文件中自动生成这个?或者我们如何做到这一点,亚马逊API网关需要这个(文档:http://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-cors.html)

asi*_*dis 4

您可以通过x-amazon-apigateway-integration swagger 扩展驱动 api 网关。

使用 Swashbuckle文档过滤器,您可以在所有路径上生成选项操作,而无需在控制器中执行相应操作。

下面是一个示例代码,它将为 swagger 中的所有路径生成一个选项操作,并添加使用 swagger 扩展在 api 网关中对这些 OPTION 方法生成模拟:

    public class AddCorsApiGatewayDocumentFilter : IDocumentFilter
    {
        private Operation BuildCorsOptionOperation()
        {
            var response = new Response
            {
                Description = "Successful operation",
                Headers = new Dictionary<string, Header>
                {
                    { "Access-Control-Allow-Origin", new Header(){Type="string",Description="URI that may access the resource" } },
                    { "Access-Control-Allow-Methods", new Header(){Type="string",Description="Method or methods allowed when accessing the resource" } },
                    { "Access-Control-Allow-Headers", new Header(){Type="string",Description="Used in response to a preflight request to indicate which HTTP headers can be used when making the request." } },
                }
            };
            return new Operation
            {
                Consumes = new List<string> { "application/json" },
                Produces = new List<string> { "application/json" },
                Responses = new Dictionary<string, Response>{{"200",response}}
            };
        }

        private object BuildApiGatewayIntegrationExtension()
        {
            return new
            {
                responses = new
                {
                    @default = new
                    {
                        statusCode = "200",
                        responseParameters = new Dictionary<string, string>
                            {
                                { "method.response.header.Access-Control-Allow-Methods", "'POST,GET,OPTIONS'" },
                                { "method.response.header.Access-Control-Allow-Headers", "'Content-Type,X-Amz-Date,Authorization,X-Api-Key'"},
                                { "method.response.header.Access-Control-Allow-Origin", "'*'"}
                            }
                    },
                },
                passthroughBehavior = "when_no_match",
                requestTemplates = new Dictionary<string, string> { { "application/json", "{\"statusCode\": 200}" } },
                type = "mock"
            };
        }

        public void Apply(SwaggerDocument swaggerDoc, DocumentFilterContext context)
        {
            foreach (var path in swaggerDoc.Paths)
            {
                var corsOptionOperation = BuildCorsOptionOperation();
                var awsApiGatewayExtension = BuildApiGatewayIntegrationExtension();
                corsOptionOperation.Extensions.Add("x-amazon-apigateway-integration", awsApiGatewayExtension);
                path.Value.Options = corsOptionOperation;
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

不要忘记在 swashbuckle 中注册该过滤器:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc();
        services.AddSwaggerGen(c =>
        {
            c.SwaggerDoc("v1", new Info { Title = "My API", Version = "v1" });
            c.DocumentFilter<AddCorsApiGatewayDocumentFilter>();
        });
    }
Run Code Online (Sandbox Code Playgroud)