Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.2k views
in Technique[技术] by (71.8m points)

reverse proxy - Starlette's url_for doesn't create links with https scheme behind Nginx (via uvicorn)

I've tried everything:

@Starlette:

routes = [
    Mount("/static/", StaticFiles(directory=parent+fs+"decoration"+fs+"static"), name="static"),
    Route(....),
    Route(....),
]

@Uvicorn:

--forwarded-allow-ips=domain.com
--proxy-headers

@url_for:

_external=True
_scheme="https"

@nginx:

proxy_set_header Subdomain $subdomain;
proxy_set_header Host $http_host;
proxy_pass http://localhost:7000/;
proxy_set_header X-Forwarded-For $remote_addr;
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 $server_name;
proxy_redirect     http://$http_host/ https://$http_host/;
include proxy_params;
server {
    if ($host = sub.domain.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    listen 80 ;
    listen [::]:80 ;
    server_name sub.domain.com;
    return 404; # managed by Certbot

}

If I open a .css or .js link, nginx renders it to https.

When I allow Firefox to ignore the unsafe content, the whole page is rendered correctly at the production server.

Let's encrypt works perfectly with the whole domain, no issues with the certificate.

question from:https://stackoverflow.com/questions/66051867/starlettes-url-for-doesnt-create-links-with-https-scheme-behind-nginx-via-uvi

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I think uvicorn's --forwarded-allow-ips=domain.com part needs to have the IP of your Nginx server because it's what's doing the forwarding. (ie change "domain.com" to IP of your nginx server) Note you can also use the environment variable FORWARDED_ALLOW_IPS=* or FORWARDED_ALLOW_IPS=1.2.3.4 instead (useful if running uvicorn behind gunicorn behind nginx)

For other readers landing here: I was having the same problem because I failed to configure my "server" config section to actually forward the X-Forwarded-Proto and X-Forwarded-For headers so that uvicorn can get them. Here's an example of what I needed:

 server {
        server_name example.com
        location / {
            proxy_redirect     off;
# These are the critical headers needed by uvicorn to honor HTTPS in url_for :
            proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header   X-Forwarded-Proto $scheme;
# These are just some other headers you may find useful
            proxy_set_header   Host $host;
            proxy_set_header   X-Real-IP $remote_addr;
            proxy_set_header   X-Forwarded-Host $server_name;

           ...
        }


    listen 443 ssl; 

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...