且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

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

更新时间:2023-09-29 08:10:10

可以通过x-amazon-apigateway-integration swagger 扩展.

You can drive api gateway through x-amazon-apigateway-integration swagger extension.

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

Using Swashbuckle document filter, you can generate a option operation on all your paths without corresponding action in your controller.

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

Here is a sample code that will generate an option operation for all paths in your swagger and add use swagger extensions to generate a mock in api gateway on these OPTION methods:

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

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

Do not forget to register that filter in swashbuckle:

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