当应用程序要通过只发布/API下路径的反向代理访问时,我如何在我的RESTful API应用程序中生成到其他资源的绝对链接?
我的应用程序是一个API,具有常见的路由布局,如/API、/swagger和/health。它发布在我雇主的API管理层上,路径为/business-area/ap-name/v1。直接和通过API网关调用API总的工作原理是:调用
https://api-gateway.company.com/business-area/api-name/v1/some-resource
导致内部调用
https://my-app.company.com/api/some-resource
.
问题是
我的应用程序响应中的链接直接指向后端应用程序
(
https://my-app.company.com/api/another-resource
),而不是API网关(
https://api-gateway.company.com/business-area/api-name/v1/another-resource
). 它们是使用生成的
IUrlHelper
.
我通过解决了域
ForwardedHeadersMiddleware
以及通过API管理上的策略添加X-Forwarded-Host。遗憾的是,我们只允许使用非常简单的策略,所以如果我们使用多个网关发布API,当前的解决方案将只生成到单个网关的链接。但这是一个有待解决的问题;现在工作正常。
我无法很好地找到工作的道路。
我尝试使用中间件更改路径,如中所示
the ASP.NET Core behind proxy docs
:
app.Use((context, next) =>
{
context.Request.PathBase = "/business-area/api-name/v1";
if (context.Request.Path.StartsWithSegments("/api", out var remainder))
{
context.Request.Path = remainder;
}
return next();
});
当我把这个中间件插入管道的高处时,它会破坏路由,但如果我把它插入得足够低,路由就可以正常工作,只会影响链路生成。但似乎只有PathBase的更改才真正影响链接生成,因为/api仍在生成的URI中。不过,我可以看到请求对象的Path确实发生了更改,所以可能只是链接生成直接使用路由信息,而不通过我的中间件,这是有道理的,但它排除了中间件解决方案。
在我自己的实现中包装标准的IUrlHelper并对其返回的URL进行后处理是一个好方法吗?我不知道该怎么做。我使用ControllerBase中的IUrlHelper。Url属性和调试器告诉它实际上是Microsoft的一个实例。AspNetCore。Mvc。路由。EndpointRoutingUrlHelper。在每个动作中进行包装似乎都是错误的(重复、容易出错)。
改变路由以使/api移动到根是我的最后选择,因为它混淆了名称空间:像/health和/swagger这样的技术端点将存在于api的实际资源中。在保持链接正常工作的同时,有没有合理的方法可以避免这种情况?这一切看起来都是一个相当标准的问题,我很惊讶我找不到如何解决它。
我们使用。NET 5,我们将迁移到。NET 6,如果这有什么不同的话。