You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在反向代理后的ASP.NET Core Web API中使用NSwag.AspNetCore配置Swagger的BaseUrl

解决反向代理下NSwag Swagger的Base URL问题

你遇到的是反向代理场景下NSwag Swagger的经典问题——容器里的API只认自己的localhost:5000地址,但反向代理把外部的https://my.domain.com映射过来,导致Swagger的Base URL显示错误,发起请求时也直接往容器内部地址发,自然没法正常工作。下面给你两种靠谱的解决方案:

方案一:自动识别真实请求地址(推荐,适配多环境)

这种方式让Swagger自动从反向代理传递的请求头里获取真实的外部地址,不用硬编码域名,不管是开发、测试还是生产环境都能通用。

步骤1:让ASP.NET Core信任反向代理的转发头

首先得让ASP.NET Core知道反向代理传过来的真实请求信息(比如是http还是https,外部域名是什么)。在Startup.csConfigureServices方法里加这段代码:

services.AddHttpContextAccessor(); // 注入HttpContext访问器,用来拿当前请求的信息

services.Configure<ForwardedHeadersOptions>(options =>
{
    // 开启识别这几个转发头:客户端IP、请求协议、外部域名
    options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto | ForwardedHeaders.XForwardedHost;
    // 把反向代理的IP加到信任列表里(比如Docker的网关IP,你得根据自己的实际环境改,能加多个)
    options.KnownProxies.Add(IPAddress.Parse("172.17.0.1"));
});

步骤2:配置NSwag动态设置Base URL

修改AddSwaggerDocument的配置,在PostProcess里用当前请求的真实地址设置Swagger的服务器信息:

services.AddSwaggerDocument(config =>
{
    config.PostProcess = (document, context) =>
    {
        var request = context.HttpContext.Request;
        // 拼出真实的Base URL:协议 + 域名(带端口的话也会自动带上)
        var baseUrl = $"{request.Scheme}://{request.Host.Value}";
        // 清空默认的服务器配置,换成真实的地址
        document.Servers.Clear();
        document.Servers.Add(new OpenApiServer { Url = baseUrl });
        
        // 保留你原来的文档信息配置
        document.Info.Version = "v1";
        document.Info.Title = "...";
    };
});

步骤3:让转发头中间件先执行

Configure方法里,一定要把UseForwardedHeaders放在UseOpenApiUseSwaggerUi3前面,这样后面的Swagger中间件才能拿到真实的请求信息:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    ...
    app.UseForwardedHeaders(); // 这个要放前面!
    app.UseOpenApi();
    app.UseSwaggerUi3();
    ...
}

额外提醒:反向代理的配置也得跟上

你的反向代理(比如Nginx、Traefik)得正确设置转发头,不然ASP.NET Core拿不到真实信息。以Nginx为例,在对应的location块里加这些配置:

proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_pass http://localhost:5000; // 这里填你的容器内部地址

方案二:手动指定固定Base URL(适合固定生产域名)

如果你的生产域名是固定死的,也可以直接把Base URL硬编码到Swagger里,简单粗暴:

services.AddSwaggerDocument(config =>
{
    config.PostProcess = document =>
    {
        document.Info.Version = "v1";
        document.Info.Title = "...";
        // 清空默认的服务器配置,换成生产环境的域名
        document.Servers.Clear();
        document.Servers.Add(new OpenApiServer { Url = "https://my.domain.com" });
    };
});

这种方式虽然简单,但不够灵活,只能用在固定域名的场景,没法适配多个环境。

验证效果

配置好重新部署后,你再去看生产环境的Swagger页面:

  • 标题下面的Base URL会显示成https://my.domain.com
  • 发起API请求时,请求地址会自动用https://my.domain.com/api,再也不会往localhost:5000发了

内容的提问来源于stack exchange,提问作者TOG

火山引擎 最新活动