如何使用 Swagger 生成选项(CORS)
How to generate Options(CORS) with Swagger
对于我们正在处理的项目,我们会自动生成一个 Swagger 文件。但是此时此刻我们正在为 CORS 部分而苦苦挣扎。
我们正在使用 Amazon API 网关导入 api 功能。要将其与 Swagger 和 CORS 结合使用,我们必须在我们的源代码中创建一个额外的操作(操作),允许每个 api 方法(操作)使用 CORS(选项)!
例如:
[HttpOptions]
[Route("{id}")]
[ProducesResponseType((int)HttpStatusCode.OK)]
public IActionResult UserOptions()
{
return new OkResult();
}
如您所见,这会使代码更脏。这是一个临时解决方案,但我们找不到其他方法。有什么办法可以在 swagger 定义文件中自动生成这个吗?或者我们如何做到这一点,Amazon API 网关需要这个(文档:http://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-cors.html)
使用控制台中简单的一键式功能执行 'Enable CORS' 的步骤,然后部署 API,最后转到舞台并将 API 导出回昂首阔步。
现在您可以检查 swagger 以查看如何在您自己的 swagger 中配置 CORS。
您可以通过 x-amazon-apigateway-integration swagger 扩展驱动 api 网关。
使用 Swashbuckle document filter,您可以在所有路径上生成选项操作,而无需在控制器中执行相应操作。
这里是一个示例代码,它将为您的 swagger 中的所有路径生成一个选项操作,并添加使用 swagger 扩展在这些 OPTION 方法的 api 网关中生成模拟:
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 中注册该过滤器:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new Info { Title = "My API", Version = "v1" });
c.DocumentFilter<AddCorsApiGatewayDocumentFilter>();
});
}
我遇到了同样的问题,我最终在 Java 中创建了一个实用程序,它会自动将这些 headers 添加到 Swagger JSON。在将其导入 API 网关之前,您可以 运行 它并导入在所有方法中启用了 CORS 的输出 JSON
https://github.com/anandlalvb/SwaggerToAPIGateway
将这些 headers 添加到 Swagger JSON 中的所有方法是一项繁琐的任务。
"headers": {
"Access-Control-Allow-Origin": {
"type": "string"
},
"Access-Control-Allow-Methods": {
"type": "string"
},
"Access-Control-Allow-Headers": {
"type": "string"
}
}
我希望这个实用程序可以帮助您轻松做到这一点
然而,结合 Azure API 管理,我遇到了完全相同的问题。我使用了asidis的代码并根据我的需要对其进行了修改。
显然,我删除了 AWS 扩展部分,并使用了更新版本的 Swashbuckle.AspNetCore 包 (5.5.1)
public class CorsDocumentFilter : IDocumentFilter
{
private const string AcaOrigin = "Access-Control-Allow-Origin";
private const string AcaMethods = "Access-Control-Allow-Methods";
private const string AcaHeaders = "Access-Control-Allow-Headers";
private static OpenApiOperation BuildCorsOptionOperation(OpenApiOperation operation)
{
var response = new OpenApiResponse
{
Description = "Successful operation",
Headers = new Dictionary<string, OpenApiHeader>
{
{ AcaOrigin, new OpenApiHeader {Description = "URI that may access the resource" } },
{ AcaMethods, new OpenApiHeader {Description = "Method or methods allowed when accessing the resource" } },
{ AcaHeaders, new OpenApiHeader {Description = "Used in response to a preflight request to indicate which HTTP headers can be used when making the request." } },
}
};
return new OpenApiOperation
{
Summary = "CORS Preflight request",
// Path parameters are required for Azure APIM
Parameters = operation.Parameters.Where(x => x.In == ParameterLocation.Path).ToList(),
Tags = new List<OpenApiTag> { new OpenApiTag { Name = "CORS" } },
Responses = new OpenApiResponses
{
{ "200", response }
},
};
}
public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
{
foreach (var path in swaggerDoc.Paths)
{
var operation = path.Value.Operations.Values.First();
var corsOptionOperation = BuildCorsOptionOperation(operation);
path.Value.Operations.Add(OperationType.Options, corsOptionOperation);
}
}
}
对于我们正在处理的项目,我们会自动生成一个 Swagger 文件。但是此时此刻我们正在为 CORS 部分而苦苦挣扎。
我们正在使用 Amazon API 网关导入 api 功能。要将其与 Swagger 和 CORS 结合使用,我们必须在我们的源代码中创建一个额外的操作(操作),允许每个 api 方法(操作)使用 CORS(选项)! 例如:
[HttpOptions]
[Route("{id}")]
[ProducesResponseType((int)HttpStatusCode.OK)]
public IActionResult UserOptions()
{
return new OkResult();
}
如您所见,这会使代码更脏。这是一个临时解决方案,但我们找不到其他方法。有什么办法可以在 swagger 定义文件中自动生成这个吗?或者我们如何做到这一点,Amazon API 网关需要这个(文档:http://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-cors.html)
使用控制台中简单的一键式功能执行 'Enable CORS' 的步骤,然后部署 API,最后转到舞台并将 API 导出回昂首阔步。
现在您可以检查 swagger 以查看如何在您自己的 swagger 中配置 CORS。
您可以通过 x-amazon-apigateway-integration swagger 扩展驱动 api 网关。
使用 Swashbuckle document filter,您可以在所有路径上生成选项操作,而无需在控制器中执行相应操作。
这里是一个示例代码,它将为您的 swagger 中的所有路径生成一个选项操作,并添加使用 swagger 扩展在这些 OPTION 方法的 api 网关中生成模拟:
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 中注册该过滤器:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new Info { Title = "My API", Version = "v1" });
c.DocumentFilter<AddCorsApiGatewayDocumentFilter>();
});
}
我遇到了同样的问题,我最终在 Java 中创建了一个实用程序,它会自动将这些 headers 添加到 Swagger JSON。在将其导入 API 网关之前,您可以 运行 它并导入在所有方法中启用了 CORS 的输出 JSON
https://github.com/anandlalvb/SwaggerToAPIGateway
将这些 headers 添加到 Swagger JSON 中的所有方法是一项繁琐的任务。
"headers": {
"Access-Control-Allow-Origin": {
"type": "string"
},
"Access-Control-Allow-Methods": {
"type": "string"
},
"Access-Control-Allow-Headers": {
"type": "string"
}
}
我希望这个实用程序可以帮助您轻松做到这一点
然而,结合 Azure API 管理,我遇到了完全相同的问题。我使用了asidis的代码并根据我的需要对其进行了修改。
显然,我删除了 AWS 扩展部分,并使用了更新版本的 Swashbuckle.AspNetCore 包 (5.5.1)
public class CorsDocumentFilter : IDocumentFilter
{
private const string AcaOrigin = "Access-Control-Allow-Origin";
private const string AcaMethods = "Access-Control-Allow-Methods";
private const string AcaHeaders = "Access-Control-Allow-Headers";
private static OpenApiOperation BuildCorsOptionOperation(OpenApiOperation operation)
{
var response = new OpenApiResponse
{
Description = "Successful operation",
Headers = new Dictionary<string, OpenApiHeader>
{
{ AcaOrigin, new OpenApiHeader {Description = "URI that may access the resource" } },
{ AcaMethods, new OpenApiHeader {Description = "Method or methods allowed when accessing the resource" } },
{ AcaHeaders, new OpenApiHeader {Description = "Used in response to a preflight request to indicate which HTTP headers can be used when making the request." } },
}
};
return new OpenApiOperation
{
Summary = "CORS Preflight request",
// Path parameters are required for Azure APIM
Parameters = operation.Parameters.Where(x => x.In == ParameterLocation.Path).ToList(),
Tags = new List<OpenApiTag> { new OpenApiTag { Name = "CORS" } },
Responses = new OpenApiResponses
{
{ "200", response }
},
};
}
public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
{
foreach (var path in swaggerDoc.Paths)
{
var operation = path.Value.Operations.Values.First();
var corsOptionOperation = BuildCorsOptionOperation(operation);
path.Value.Operations.Add(OperationType.Options, corsOptionOperation);
}
}
}