Skip to content

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

@Lepiloff

Description

@Lepiloff

First Check

  • I added a very descriptive title to this issue.
  • I used the GitHub search to find a similar issue and didn't find it.
  • I searched the FastAPI documentation, with the integrated search.
  • I already searched in Google "How to X in FastAPI" and didn't find any information.
  • I already read and followed all the tutorial in the docs and didn't find an answer.
  • I already checked if it is not related to FastAPI but to Pydantic.
  • I already checked if it is not related to FastAPI but to Swagger UI.
  • I already checked if it is not related to FastAPI but to ReDoc.

Commit to Help

  • I commit to help with one of those options 👆

Example Code

main.py

from fastapi import FastAPI, Request, Form
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates

from db import database
from helpers.middleware import get_user_notifications, set_custom_attr
from models.users import users
from routes import api_router
from sessions.core.base import redis_cache

app = FastAPI()

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

views.py

@router.get('/', response_class=HTMLResponse)
async def main_page(request: Request,
                    user: User = Depends(UserService.get_authenticated_user_id)
                    ):
    return templates.TemplateResponse('base.html',
                                      context={
                                          'request': request,
                                          'user': user,
                                      }
                                      )

html

  <link type="text/css" href="{{ url_for('static', path='/css/materialize.min.css') }}" rel="stylesheet">
  <link type="text/css" href="{{ url_for('static', path='/css/custom.css') }}" rel="stylesheet">

Description

I run the application in the docker via Uvicorn and use nginx as a proxy server. Everything was working until I configured ssl and started using https protocol. Now when I click on the team-mate.app get

Mixed Content: The page at 'https://team-mate.app/' was loaded over HTTPS, but requested an insecure stylesheet 'http://team-mate.app/static/css/materialize.min.css'. This request has been blocked; the content must be served over HTTPS.

I tried the advice I found and ran Uvicorn through --proxy-headers

Dockerfile
....
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000", "--proxy-headers"]

docker-compose.yaml

....
    command: sh -c "alembic upgrade head && uvicorn main:app --host 0.0.0.0 --port 8000 --reload --proxy-headers"

But nothing has changed. The problem remains.
Maybe I misunderstood the advice or the nginx config needs to be edited somehow.

The second way I used

from fastapi.middleware.httpsredirect import HTTPSRedirectMiddleware
app = FastAPI()
app.add_middleware(HTTPSRedirectMiddleware)

But got HTTP/1.0" 307 Temporary Redirect for all my urls

Operating System

Linux

Operating System Details

No response

FastAPI Version

fastapi==0.89.1

Python Version

3.10.6

Additional Context

I run the application in the docker via Uvicorn and use nginx as a proxy server. Everything was working until I configured ssl and started using https protocol.

nginx config

server {
    listen 80;
    server_name team-mate.app;
    location /.well-known/acme-challenge/ {
        root /var/www/certbot;
    }
    location / {
        return 301 https://$host$request_uri;
    }
}
server {
    listen 443 ssl;
    server_name team-mate.app;
    server_tokens off;

    location /static/ {
        gzip            on;
        gzip_buffers    8 256k;
        root /app;
    }

    ssl_certificate /etc/letsencrypt/live/team-mate.app/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/team-mate.app/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    location / {
        proxy_pass http://web:8000;
        proxy_set_header    Host                $http_host;
        proxy_set_header    X-Real-IP           $remote_addr;
        proxy_set_header    X-Forwarded-For     $proxy_add_x_forwarded_for;
    }
}

Dockerfile

FROM tiangolo/uvicorn-gunicorn-fastapi:python3.9

WORKDIR /app

COPY ./requirements.txt /app/requirements.txt

RUN pip install --no-cache-dir -r /app/requirements.txt

COPY . .

EXPOSE 8000

CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

docker-compose.yaml


version: '3.9'

services:
  web:
    env_file: .env
    build: .
    command: sh -c "alembic upgrade head && uvicorn main:app --host 0.0.0.0 --port 8000 --reload"
    volumes:
      - .:/app
    ports:
      - 8000:8000
    depends_on:
      - db
      - redis
      .....
      .....

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions