asp.net-core - 对 nginx 反向代理背后的应用程序进行故障排除,因为 POST/PUT 请求回复错误 400(错误请求)

标签 asp.net-core nginx nginx-reverse-proxy

我第一次尝试在 Linux 上托管我的 Angular/ASP.net Core 3.1 应用程序。

Nginx 位于端口 80 上,提供静态文件并作为将传递到 .NET/kestrel 服务器的 api 部分的反向代理。

问题是我在任何包含正文的 Web API 请求(如 POST 和 PUT,但 GET 没问题)上系统地收到 400 状态代码错误(错误请求)。

我通过一个中间件添加了一些日志,只是为了看看我是否能得到请求。基本上是这样的:

app.Use(async (context, next) => {
    context.Request.EnableBuffering();
    string reqBody;
    using (var reader = new StreamReader(context.Request.Body))
    {
        reqBody = await reader.ReadToEndAsync();
        context.Request.Body.Seek(0, SeekOrigin.Begin);
        ms_oLogger.Debug($"Incoming request: METHOD={context.Request.Method} PATH={context.Request.Path} BODY=\"{reqBody}\"");
    }
    await next();
});

这只是记录 GET 请求的内容,但没有显示有问题的 PUT/POST 请求的内容...我可以断定这只是一个 nginx 问题吗?

我还在 nginx 上为给定的“/api”位置启用了日志,但我不知道发生了什么......我怎么知道哪个层生成了 400 状态代码?

EDIT1:我开始了一个空白的新项目,只是一个包含一个 GET 和一个 POST 方法的糟糕 Web API 项目,只是为了检查我的应用程序是否有问题,但我仍然遇到了问题。 所以我设置了一个新的 ubuntu 服务器(这次是 ubuntu 服务器而不是桌面版),现在它可以工作了!!! 我比较了配置等......但无法弄清楚出了什么问题!.... 但我最初的问题仍然有效:如何解决问题的根源?

EDIT2:这是我的 default.conf:

server {
        listen 80 default_server;
        listen [::]:80 default_server;

        root /var/www/html;

        index index.html index.htm index.nginx-debian.html;

        server_name _;

        location / {
                try_files $uri $uri/ =404;
        }

        location /fusion {
                root /opt/fichet/WebUI/NgApp;
        }

        location /fusion/api  {
               proxy_pass http://localhost:5000/api;
                error_log          /var/log/nginx/fusion_error_logs.log debug;
                access_log         /var/log/nginx/fusion_access.log;
                proxy_http_version 1.1;
                proxy_cache_bypass  $http_upgrade;
                proxy_set_header Upgrade           $http_upgrade;
                proxy_set_header Connection        "upgrade";
                proxy_set_header Host              $host;
                proxy_set_header X-Real-IP         $remote_addr;
                proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Proto $scheme;
                proxy_set_header X-Forwarded-Host  $host;
                proxy_set_header X-Forwarded-Port  $server_port;
        }
}

似乎没有启用防火墙(“sudo ufw status verbose”告诉我们它是“inactive”)

最佳答案

从您的 nginx 配置中删除这些行。

                proxy_cache_bypass  $http_upgrade;
                proxy_set_header Upgrade           $http_upgrade;
                proxy_set_header Connection        "upgrade";

这些 header 用于 WebSocket 连接,不应出现在非 WebSocket 请求中。我的猜测是您的上游服务器不介意它们处理 GET 请求,但出于某种原因处理 POST/PUT。

如果您不使用 websockets,您可以将它们移除。

如果您使用的是 websockets,则需要 nginx 根据请求是否为 websockets 添加或不添加这些 header 。这样的事情应该有效:

    http {
        map $http_upgrade $connection_upgrade {
            default upgrade;
            ''      close;
        }

        server {
            ...

            location /fusion/api {
                proxy_pass ...
                ...
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection $connection_upgrade;
            }
        }

参见 here了解更多信息。

关于asp.net-core - 对 nginx 反向代理背后的应用程序进行故障排除,因为 POST/PUT 请求回复错误 400(错误请求),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62392574/

相关文章:

asp.net-mvc - ASP.Net 5 MVC6 select taghelper 产生错误的输出

nginx - 如何在 kubernetes 中扩展 Web 应用程序?

docker - 当上游节点不可用时,Nginx 容器退出并显示代码 1

c# - 如何将asp.net core mvc项目分离成多个程序集(.dll)?

c# - 在vNext中从appsetting.json读取启动后的连接字符串

c# - Microsoft.Extensions.Caching.Memory.IMemoryCache 线程安全吗

nginx - GKE配置502错误网关上的Ingress-nginx

Docker Compose 和 Nginx 反向代理 : I can't access the backend through the proxy

socket.io - 使用 Traefik 或 NGINX 在 Docker Swarm 上正确处理 Socket.io