FastApi(Starlette)+ NGINX代理:请求对象中的URL方案不正确?

bybem2ql  于 2023-08-03  发布在  Nginx
关注(0)|答案(1)|浏览(154)

我想知道以下内容

  • Starlette如何在Request对象中设置“url”属性-特别是在NGINX代理背后操作时。
  • 如何在NGINX级别上操作request.url-设置代理头根本不会修改它?
  • 如何通过Starlette中间件操作request.url--不知何故,我所做的没有任何效果?

设置是这样的:
我有一个FastAPI应用程序在NGINX代理后面运行。通过浏览器,我通过HTTPS(https://www.example.com)向NGINX发送请求,但无论我做什么,Starlette的request.url总是http://www.example.com
我制作了一个小型FastAPI端点用于演示

@app.get("/test")
def some_test(request: Request):
    return {"request.url": request.url,
            "request['headers']": request["headers"],
            "request.client": request.client}

字符串
在下面的截图中,我展示了我得到的内容(域名是匿名的;设置为xyz):x1c 0d1x的数据
1.我在浏览器中调用https://www.example.com/test
1.在控制台中,我看到请求正确地发送到https://www.example.com/test
1.但是当查看Starlette的Request.url时,它显示为http://www.example.com/test
这种行为是应该的吗?在屏幕截图中,我还打印了hostx-forwarded-protox-forwarded-schema,我将NGINX配置设置为HTTPS,但对象Request根本没有被修改。
如何在NGINX或FastAPI/Starlette级别上纠正这个问题?

  • 我已经尝试设置各种命令,如
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Scheme $scheme;

,但没有成功。

  • 我试着写一个自定义的Starlette中间件(我知道这很难看,但我想尝试一下,以更好地了解发生了什么)
from fastapi import Request
from starlette.datastructures import URL

@app.middleware("http")
async def some_middlware(request: Request, call_next):

    if "/test" in str(request.url):
        print(f"before {request.url}")
        request._url = URL(str(request.url).replace("http", "https"))
        print(f"after {request.url}")

    response = await call_next(request)
    return response

,但这也不会修改响应中显示的request.url

hgb9j2n6

hgb9j2n61#

现在模式的代理可以工作了。
问题是:
在我的Dockerfile看起来像

ENTRYPOINT ["uvicorn", "main:app", "--proxy-headers", "--forwarded-allow-ips='*'", "--host", "0.0.0.0"]

字符串
--forwarded-allow-ips参数中的引号不起作用。入口点应改为

ENTRYPOINT ["uvicorn", "main:app", "--proxy-headers", "--forwarded-allow-ips=*", "--host", "0.0.0.0"]


提示:为了更清楚一点,不应该允许*作为IP地址,而是应该指定IP地址。

相关问题