Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to send Authorization Header through Swagger UI using FastAPI?

In the frontend, I have the following JS function:

export const uploadFormData = async (
    token: string,
    email: string,
    formInfo: Array<Object>,
): Promise<any> => {
    const formData = new FormData();
    formData.append('email', email);
    formData.append('form_info', JSON.stringify({ formInfo }));
    return fetch(
        `${process.env.ENDPOINT}/upload_form_data/`,
        {
            method: 'POST',
            headers: {
                Authorization: `Token ${token}`,
            },
            body: formData,
        },
    ).then((response) => {
        console.log(response.body?.getReader());
        if (response.status === 404) {
            throw Error('Url not found');
        }
        if (response.status === 422) {
            throw Error('Wrong request format');
        }
        if (response.status !== 200) {
            throw Error('Something went wrong with uploading the form data.');
        }
        const data = response.json();
        return {
            succes: true,
            data,
        };
    }).catch((error) => Promise.reject(error));
};

which sends a POST request to the following endpoint in the FastAPI backend:

@app.post("/api/queue/upload_form_data/")
async def upload_form_data(
    email: str = Body(...),  
    form_info: str = Body(...), 
    authorization: str = Header(...),
    
):
    return 'form data processing'

However, it keeps throwing the following errors:

  1. In the frontend:

    POST http://localhost:8000/api/queue/upload_form_data/ 422 (Unprocessable Entity)
    Uncaught (in promise) Error: Wrong request format
    
  2. In the backend:

    POST /api/queue/upload_form_data/ HTTP/1.1" 400 Bad Request
    
  3. In Swagger UI (response body):

    {
      "detail": [
        {
          "loc": [
            "header",
            "authorization"
          ],
          "msg": "field required",
          "type": "value_error.missing"
        }
      ]
    }
    

What is wrong with the request that is causing these errors?

like image 469
benjammin Avatar asked Mar 27 '26 03:03

benjammin


1 Answers

In Swagger/OpenAPI specification, Authorization is a reserved header—along with Accept and Content-Type headers as well—for Swagger's built-in authentication/authorization functionality (see Swagger documentation). Hence, they are not allowed to be defined.

If you are using Swagger, you can't have an Authorization header parameter defined in your endpoint and expect it to work, as it would be ignored when submitting the request through Swagger UI, and you would receive a 422 Unprocessable Entity error with a body message saying that the authorization header is missing (just like the error posted in your question).

Solutions

Solution 1

If you don't need Swagger UI for testing your application, you can leave it as is and keep using JavaScript Fetch API, passing the Authorization in the headers. For example:

from fastapi import Header

@app.post('/')
def main(authorization: str = Header(...)):
    return authorization

Also, note that you don't really have to define any Header parameters in your endpoint, as you can always access them directly through the Request object, for instance:

from fastapi import Request

@app.post('/')
def main(request: Request):
    authorization = request.headers.get('Authorzation')
    return authorization

Solution 2

If you do need this to work with Swagger UI as well, one solution would be to use FastAPI's HTTPBearer, which would allow you to click on the Authorize button at the top right hand corner of your screen in Swagger UI autodocs (at /docs), where you can type your API key in the Value field. This will set the Authorization header in the request headers. Example:

from fastapi import FastAPI, Depends
from fastapi.security import HTTPBearer

app = FastAPI()
security = HTTPBearer()

@app.get('/')
def main(authorization: str = Depends(security)):
    return authorization.credentials

Alternatively, you could use APIKeyHeader with the desired name for the header (in your case, that is, Authorization), which would also allow you to click on the Authorize button in Swagger UI, in order to set the header value.

from fastapi import FastAPI, Security
from fastapi.security.api_key import APIKeyHeader

app = FastAPI()
api_key_header = APIKeyHeader(name='Authorization')

@app.get('/')
def main(api_key: str = Security(api_key_header)):
    return api_key 

Solution 3

Another solution would be to rename the authorization Header parameter to something else, e.g., token, and define this parameter as Optional in your API endpoint. Then, inside your endpoint, check if the API key is in either the token or request.headers.get('Authorization') parameter—if both return None, then this means that no token was provided. Example:

from fastapi import FastAPI, Request, Header
from typing import Optional

app = FastAPI()

@app.get('/')
def main(request: Request, token: Optional[str] = Header(None)):
    authorization = request.headers.get('Authorization')
    return token if token else authorization  
like image 151
Chris Avatar answered Mar 28 '26 15:03

Chris



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!