我想知道以下内容
- 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
这种行为是应该的吗?在屏幕截图中,我还打印了host
和x-forwarded-proto
和x-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
。
1条答案
按热度按时间hgb9j2n61#
现在模式的代理可以工作了。
问题是:
在我的Dockerfile看起来像
字符串
--forwarded-allow-ips
参数中的引号不起作用。入口点应改为型
提示:为了更清楚一点,不应该允许
*
作为IP地址,而是应该指定IP地址。