In some situations, you might need to use a **proxy** server like Traefik or Nginx with a configuration that adds an extra path prefix that is not seen by your application.
In many situations, you would use a **proxy** like Traefik or Nginx in front of your FastAPI app.
These proxies could handle HTTPS certificates and other things.
A **proxy** in front of your application would normally set some headers on the fly before sending the requests to your **server** to let the server know that the request was **forwarded** by the proxy, letting it know the original (public) URL, including the domain, that it is using HTTPS, etc.
The **server** program (for example **Uvicorn** via **FastAPI CLI**) is capable of interpreting these headers, and then passing that information to your application.
But for security, as the server doesn't know it is behind a trusted proxy, it won't interpret those headers.
You can start FastAPI CLI with the *CLI Option*`--forwarded-allow-ips` and pass the IP addresses that should be trusted to read those forwarded headers.
If you set it to `--forwarded-allow-ips="*"` it would trust all the incoming IPs.
If your **server** is behind a trusted **proxy** and only the proxy talks to it, this would make it accept whatever is the IP of that **proxy**.
<divclass="termy">
```console
$ fastapi run --forwarded-allow-ips="*"
<spanstyle="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
</div>
### Redirects with HTTPS { #redirects-with-https }
For example, let's say you define a *path operation*`/items/`:
The **proxy** intercepts the original client request and adds the special *forwarded* headers (`X-Forwarded-*`) before passing the request to the **application server**.
These headers preserve information about the original request that would otherwise be lost:
* **X-Forwarded-For**: The original client's IP address
* **X-Forwarded-Proto**: The original protocol (`https`)
* **X-Forwarded-Host**: The original host (`mysuperapp.com`)
When **FastAPI CLI** is configured with `--forwarded-allow-ips`, it trusts these headers and uses them, for example to generate the correct URLs in redirects.
## Proxy with a stripped path prefix { #proxy-with-a-stripped-path-prefix }
You could have a proxy that adds a path prefix to your application.
In these cases you can use `root_path` to configure your application.
In these cases you can use `root_path` to configure your application.
@ -10,8 +109,6 @@ The `root_path` is used to handle these specific cases.
And it's also used internally when mounting sub-applications.
And it's also used internally when mounting sub-applications.
## Proxy with a stripped path prefix { #proxy-with-a-stripped-path-prefix }
Having a proxy with a stripped path prefix, in this case, means that you could declare a path at `/app` in your code, but then, you add a layer on top (the proxy) that would put your **FastAPI** application under a path like `/api/v1`.
Having a proxy with a stripped path prefix, in this case, means that you could declare a path at `/app` in your code, but then, you add a layer on top (the proxy) that would put your **FastAPI** application under a path like `/api/v1`.
In this case, the original path `/app` would actually be served at `/api/v1/app`.
In this case, the original path `/app` would actually be served at `/api/v1/app`.
@ -73,7 +170,7 @@ To achieve this, you can use the command line option `--root-path` like:
<divclass="termy">
<divclass="termy">
```console
```console
$ fastapi run main.py --root-path /api/v1
$ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
<spanstyle="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
<spanstyle="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
```
@ -103,7 +200,7 @@ Then, if you start Uvicorn with:
<divclass="termy">
<divclass="termy">
```console
```console
$ fastapi run main.py --root-path /api/v1
$ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
<spanstyle="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
<spanstyle="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
```
@ -224,7 +321,7 @@ And now start your app, using the `--root-path` option:
<divclass="termy">
<divclass="termy">
```console
```console
$ fastapi run main.py --root-path /api/v1
$ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
<spanstyle="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
<spanstyle="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
@ -190,6 +190,38 @@ To do that, and to accommodate different application needs, there are several wa
All this renewal process, while still serving the app, is one of the main reasons why you would want to have a **separate system to handle HTTPS** with a TLS Termination Proxy instead of just using the TLS certificates with the application server directly (e.g. Uvicorn).
All this renewal process, while still serving the app, is one of the main reasons why you would want to have a **separate system to handle HTTPS** with a TLS Termination Proxy instead of just using the TLS certificates with the application server directly (e.g. Uvicorn).
When using a proxy to handle HTTPS, your **application server** (for example Uvicorn via FastAPI CLI) doesn't known anything about the HTTPS process, it communicates with plain HTTP with the **TLS Termination Proxy**.
This **proxy** would normally set some HTTP headers on the fly before transmitting the request to the **application server**, to let the application server know that the request is being **forwarded** by the proxy.
Nevertheless, as the **application server** doesn't know it is behind a trusted **proxy**, by default, it wouldn't trust those headers.
But you can configure the **application server** to trust the *forwarded* headers sent by the **proxy**. If you are using FastAPI CLI, you can use the *CLI Option*`--forwarded-allow-ips` to tell it from which IPs it should trust those *forwarded* headers.
For example, if the **application server** is only receiving communication from the trusted **proxy**, you can set it to `--forwarded-allow-ips="*"` to make it trust all incoming IPs, as it will only receive requests from whatever is the IP used by the **proxy**.
This way the application would be able to know what is its own public URL, if it is using HTTPS, the domain, etc.
This would be useful for example to properly handle redirects.
/// tip
You can learn more about this in the documentation for [Behind a Proxy - Enable Proxy Forwarded Headers](../advanced/behind-a-proxy.md#enable-proxy-forwarded-headers){.internal-link target=_blank}
///
## Recap { #recap }
## Recap { #recap }
Having **HTTPS** is very important, and quite **critical** in most cases. Most of the effort you as a developer have to put around HTTPS is just about **understanding these concepts** and how they work.
Having **HTTPS** is very important, and quite **critical** in most cases. Most of the effort you as a developer have to put around HTTPS is just about **understanding these concepts** and how they work.