Dotnet Core + Razor Pages + Nginx反向代理+隐藏URL详细信息

时间:2019-09-07 11:14:30

标签: nginx .net-core razor-pages nginx-reverse-proxy

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

这是当前直接访问红example的URL结构的示例。

  • /brands/1/products
  • /brands/2/products
  • /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>
  }
}
// /Pages/Products/Detail.cshtml
@page "/brands/{brandId}/products/{productId}"

这导致的结果是具有href之类的/brands/1/products/23值的锚点

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

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

现在的问题是2折:

  • “隐藏”的品牌ID现在公开了
  • 当用户单击http://brand1.local/brands/1/products/23时,他们会得到一个404,因为nginx网站上没有/brands的位置(应该没有)

我要实现的目标是可能的吗?:

  • 直接通过茶est进行访问会导致href值不变
  • 通过反向代理访问会导致href值不包含前缀/brand/{brandId}

1 个答案:

答案 0 :(得分:-1)

根据您的设置,我想您正在尝试将brand为多租户应用多租户。如果我正确,那么您上面的代码不正确。您应该更改代码,并从Host-Header而不是url阅读BrandId。有一些示例代码可用于从API的标头读取值:

class ProductsController
{
     [HttpGet("{id}")]
     public IActionResult GetProducts([FromHeader] string BrandId, string id)
     {
        // Call DB to get product by BrandId
     }
}

在nginx中,您应该在每个站点中添加一个代理标头。例如: proxy_set_header BrandId 1