3

I have a html file and I configured the URL of the links as below.

app.mount("/static", StaticFiles(directory="static"), name="static")

{{ url_for('static', path='css/style.css') }}

I have got the domain creation for the application with nginx and haproxy.

When the html page is loaded the css and js stylings are not being loaded as it is using http instead of https.

Flask url_for generates http instead of https when running by docker

FastAPI links created by url_for in Jinja2 template use HTTP instead of HTTPS

I went with some of the links on similar issue but didn't help as it is for html files.

When I hardcoded it worked. How can I make this static. I am using the uvicorn fastapi.

keto col
  • 31
  • 2
  • Depending on which of your proxies are terminating https, that reverse proxy needs to set `X-Forwarded-Proto` - otherwise the application behind it can't know that it's being served through https. – MatsLindh Aug 22 '22 at 20:07
  • In your NGINX configuration, try redirecting port 80 to 443. I Googled my way to what appears to be a good configuration example in the following Digital Ocean community post answer: https://www.digitalocean.com/community/questions/nginx-redirect-to-https – Jason R Stevens CFA Aug 22 '22 at 21:05
  • 1
    After adding `HTTPSRedirectMiddleware` I can't relaod the html page as well. It says ERR_TOO_MANY_REDIRECTS – keto col Aug 23 '22 at 06:45
  • @chris In answer comments I saw Use `HTTPSRedirectMiddleware`. This will enforce redirection to https on any incoming requests. My application link is already requesting the index page html in https only. when loading the html the styling links are being called as http. That is the issue. How to make it https ? – keto col Aug 23 '22 at 06:48
  • Removing url_for and replacing with href="/static/css/style.css" worked for me. – keto col Aug 23 '22 at 08:27
  • Replacing the `url_for` function with relative URLs (e.g., `href="/static/"`), as described [here](https://stackoverflow.com/a/71306247/17865804), is the easiest solution in your case. The `HTTPSRedirectMiddleware` enforces **all** incoming requests to be redirected to `HTTPS` (including requests to your static files). As for the `ERR_TOO_MANY_REDIRECTS` error, there might likely be some issue with redirection when you are behind a proxy, see [this](https://github.com/tiangolo/fastapi/issues/199#issuecomment-1210368890). Have a look [here](https://serverfault.com/q/933355) as well. – Chris Aug 23 '22 at 09:46
  • You may also want to have a look at Uvicorn's documentation on [Running behind Nginx](https://www.uvicorn.org/deployment/#running-behind-nginx). – Chris Aug 23 '22 at 15:13

2 Answers2

5

In my case, FastAPI and uvicorn was behind reverse proxy on fly.io and have to add --proxy-headers and --forwarded-allow-ips '*' to my uvicorn command. Full example:

uvicorn app:app --host 0.0.0.0 --port 8080 --proxy-headers --forwarded-allow-ips '66.241.124.179'

To find IP address:

➜ fly ips list      
VERSION IP                  TYPE            REGION  CREATED AT           
v6      2a09:8280:1::1:de8b public          global  2023-02-11T11:24:14Z    
v4      66.241.124.179      public (shared)     

How it's works?

  1. Uvicorn starts hanlding incomming request.
  2. If --proxy-headers is enabled, uvicorn pass proxy headers further: X-Forwarded-Proto, X-Forwarded-For, ...
  3. Then uvicorn for incoming request trying to detect schema in ProxyHeadersMiddleware middleware
  4. In that middleware uvicorn parses client IP address from X-Forwarded-For header.
  5. Then compares that IP address to trusted list (--forwarded-allow-ips)
  6. If address is trusted, then extracts schema from X-Forwarded-Proto
Yevhenii Hyzyla
  • 183
  • 4
  • 5
-1

One way to ensure that url_for always generates https URLs is to set the PREFERRED_URL_SCHEME configuration option to https in your application. This will instruct url_for to use the https scheme unless explicitly overridden. Here is an example:

app = FastAPI()
app.config["PREFERRED_URL_SCHEME"] = "https"
GoldFiSh
  • 1
  • 1