繁体   English   中英

如何在 Ocelot 网关中处理 cors 策略和预检请求?

[英]How to handle cors policy and preflight requests in Ocelot gateway?

我有一个 Ocelot 网关来路由和处理我的 API 服务器请求。 问题是我在 API 中使用 CORS 策略,当请求来自 Web 浏览器到 API 并且我需要获取预检请求并路由到特定 API 时。 现在我无法解决 Ocelot 网关中的问题。 我该如何解决?

以下代码是一个 API 示例:

[EnableCors(origins: "*", headers: "*", methods: "*")]
[Route("api/Balance")]
public GeneralResult<DTOResponse> Post(DTORequest req)
{
    var result = new GeneralResult<DTOResponse>();
    try
    {
    .
    .
    .
    }
    catch (Exception ex)
    }
        return result;
    }
}

经过大量搜索和查看不同示例后,我找到了解决问题的方法:

正如您在 预检请求中看到的那样,如果从浏览器端调用 API,首先会发送预检请求以确保浏览器与服务器之间连接的真实性。 如果我们直接向 API 发出请求,一切都很好,但是当我们使用Ocelot时,情况就有点不同了。 在这种情况下, Ocelot必须识别预检类型请求,据我所知,这在Ocelot中没有完成,必须由开发人员处理。 为了解决这个问题,我首先在ConfigureServices部分使用了如下代码:

 public void ConfigureServices(IServiceCollection services)
    {
        services.AddOcelot();
        services.AddCors(o =>
        {
            o.AddPolicy("CorsPolicy", p =>
            {
                p.AllowAnyOrigin()
                .AllowAnyMethod()
                .AllowAnyHeader();
            });
        });
    }

然后在配置部分,我添加了以下代码:

 public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        app.UseCors("CorsPolicy");
        app.UsePreflightRequestHandler();
    }

正如您在上面的代码片段中所看到的,我首先在 ConfigureServices 部分中将CORS Policy设置添加到服务中,然后在配置部分中使用它。

然后,我添加了一个名为UsePreflightRequestHandler的中间件,它的使用方式是,当从浏览器发送具有选项类型的预检请求时,该请求会在中间件中进行检查,并将所需的标头添加到其中。 如果请求的类型是选项,则在中间件中检查请求并使用 OK 给出响应。 在这种情况下,浏览器已收到对预检请求的适当响应,并且该过程继续进行,并且从浏览器发送主请求。

public class PreflightRequestMiddleware
{
    private readonly RequestDelegate Next;
    public PreflightRequestMiddleware(RequestDelegate next)
    {
        Next = next;
    }
    public Task Invoke(HttpContext context)
    {
        return BeginInvoke(context);
    }
    private Task BeginInvoke(HttpContext context)
    {
        context.Response.Headers.Add("Access-Control-Allow-Credentials", new[] { "true" });
        context.Response.Headers.Add("Access-Control-Allow-Headers", new[] { "Origin, X-Requested-With, Content-Type, Accept, Athorization, ActualUserOrImpersonatedUserSamAccount, IsImpersonatedUser" });
        context.Response.Headers.Add("Access-Control-Allow-Methods", new[] { "GET, POST, PUT, DELETE, OPTIONS" });
        if (context.Request.Method == HttpMethod.Options.Method)
        {
            context.Response.StatusCode = (int)HttpStatusCode.OK;
            return context.Response.WriteAsync("OK");
        }
        return Next.Invoke(context);
    }
}

public static class PreflightRequestExtensions
{
    public static IApplicationBuilder UsePreflightRequestHandler(this IApplicationBuilder builder)
    {
        return builder.UseMiddleware<PreflightRequestMiddleware>();
    }
}

暂无
暂无

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

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