Dotnet核心&x2B;剃刀页面+;nginx反向代理+;隐藏url详细信息

Dotnet核心&x2B;剃刀页面+;nginx反向代理+;隐藏url详细信息,nginx,.net-core,razor-pages,nginx-reverse-proxy,Nginx,.net Core,Razor Pages,Nginx Reverse Proxy,我们正在开发一个简单的Dotnet Core 2.2应用程序,使用Razor页面为客户的各种品牌提供产品信息 这是URL结构的一个示例,当前直接访问kestrel时,URL结构起作用 /brands/1/产品 /brands/2/产品 /brands/1/products/23 /brands/2/products/5 客户想要做的是在他们的每个品牌站点上配置一个反向代理,以透明地允许客户浏览新站点 我一直在使用nginx反向代理在使用直接访问时成功地模拟了这一点 以下是nginx配置的一个

我们正在开发一个简单的Dotnet Core 2.2应用程序,使用Razor页面为客户的各种品牌提供产品信息

这是URL结构的一个示例,当前直接访问kestrel时,URL结构起作用

  • /brands/1/产品
  • /brands/2/产品
  • /brands/1/products/23
  • /brands/2/products/5
客户想要做的是在他们的每个品牌站点上配置一个反向代理,以透明地允许客户浏览新站点

我一直在使用nginx反向代理在使用直接访问时成功地模拟了这一点

以下是nginx配置的一个片段

    server {
        listen       80;
        server_name brand1.local;

        location /products {
            proxy_pass http://127.0.0.1:5000/brands/1/products;
            proxy_http_version 1.1;
            proxy_set_header   Upgrade $http_upgrade;
            proxy_set_header   Connection keep-alive;
            proxy_set_header   Host $host;
            proxy_cache_bypass $http_upgrade;
            proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header   X-Forwarded-Proto $scheme;
        }
    }

    server {
        listen       80;
        server_name brand2.local;

        location /products {
            proxy_pass http://127.0.0.1:5000/brands/2/products;
            proxy_http_version 1.1;
            proxy_set_header   Upgrade $http_upgrade;
            proxy_set_header   Connection keep-alive;
            proxy_set_header   Host $host;
            proxy_cache_bypass $http_upgrade;
            proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header   X-Forwarded-Proto $scheme;
        }
    }  
这部分实现了目标,下面的代理工作

  • http://brand1.local/products
    >
    http://localhost:5000/brands/1/products
  • http://brand1.local/products/23
    >
    http://localhost:5000/brands/1/products/23
  • http://brand2.local/products
    >
    http://localhost:5000/brands/2/products
  • http://brand2.local/products/5
    >
    http://localhost:5000/brands/1/products/5
例如,当使用Razor Pages的锚定标记助手时,问题就出现了

// /Pages/Products/Index.cshtml
@{
  foreach (var product in Model.Products)
  {
    <div>
       <a asp-page="/Products/Detail" 
          asp-route-brandId="@Model.Brand.Id" 
          asp-route-productId="@product.Id">
          @product.Name
       </a>
    </div>
  }
}
这会导致锚定值
href
/brands/1/products/23

当然,在
localhost:5000上访问站点时,这是正确的

但是,当我们现在通过nginx域查看产品列表时,我们得到的是相同的
href
值,例如
/brands/1/products/23
http://brand1.local/brands/1/products/23

这里的问题有两个方面:

  • “隐藏”的品牌标识现在已公开
  • 当用户单击
    http://brand1.local/brands/1/products/23
    ,他们得到了404,因为nginx网站上没有
    /brands
    的位置(应该没有)
我试图实现的目标可能吗

  • 直接通过kestrel访问会产生
    href
    原样的值
  • 通过反向代理进行访问会导致
    href
    值不包括
    /brand/{brandId}
    前缀

根据您的设置,我猜您正在尝试使用
品牌的多租户。如果我更正了,那么上面的代码就不正确。您应该更改代码并从主机标题而不是url中读取
BrandId
。API中有用于从标头读取值的示例代码:

class ProductsController
{
     [HttpGet("{id}")]
     public IActionResult GetProducts([FromHeader] string BrandId, string id)
     {
        // Call DB to get product by BrandId
     }
}
在nginx中,您应该在每个站点中添加一个代理标头。前任:
proxy\u set\u header BrandId 1

这并不能解决问题。它只是将BrandId从url移动到标题。问题在于Razor/ASP.Net核心如何使用AnchorTagHelper编写URL。我可能会使用javascript/jquery解决这个问题,并在需要时更新href。Nope,anchortaghelper是正确的,因为您希望在下一页中使用asp route brandId=“@Model.Brand.Id”和asp route productId=“@product.Id”传递两个参数,因此.NET Core将生成正确的href。因此,它要求您创建一个代理来转发请求。在您的例子中,您希望隐藏brands/{brand_id}并保留后缀products/{product_id},这意味着您应该将brand_id隐藏在查询参数之外的某个位置(在会话、cookie、header等中)。您可以想象您在localhost:5000中运行此网站,因此您希望有一个url。但您在本地web之前添加了一个代理,将代理作为中间逻辑层转发brand_id,然后您输入时将是。这意味着您只需将web中的次要逻辑转换为代理。因此,您可以在本地web上检测两种逻辑:一种是在本地主机上运行的,另一种是代理转发器,AnchorTagHelper的输出是两个HREF,而不是一个
class ProductsController
{
     [HttpGet("{id}")]
     public IActionResult GetProducts([FromHeader] string BrandId, string id)
     {
        // Call DB to get product by BrandId
     }
}