如何使用 FastAPI 通过 Swagger UI 发送授权标头?

问题描述 投票:0回答:1

在前端,我有以下JS函数:

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));
};

向 FastAPI 后端中的以下端点发送

POST
请求:

@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'

然而,它不断抛出以下错误:

  1. 在前端:

    POST http://localhost:8000/api/queue/upload_form_data/ 422 (Unprocessable Entity)
    Uncaught (in promise) Error: Wrong request format
    
  2. 在后端:

    POST /api/queue/upload_form_data/ HTTP/1.1" 400 Bad Request
    
  3. 在 Swagger UI(响应主体)中:

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

导致这些错误的请求有什么问题?

python reactjs swagger swagger-ui fastapi
1个回答
2
投票

在 Swagger/OpenAPI 规范中,

Authorization
是一个保留标头——与
Accept
Content-Type
标头一样——用于 Swagger 的内置 authentication/authorization 功能(参见 Swagger 文档)。因此,它们不允许被定义。

如果您使用的是 Swagger,则不能在端点中定义

Authorization
标头参数并期望它起作用,因为在通过 Swagger UI 提交请求时它会被忽略,并且您会收到
422 Unprocessable Entity
错误正文消息说
authorization
标头正在缩小(就像您问题中发布的错误一样)。

解决方案

解决方案 1

如果您 不需要 需要 Swagger UI 来测试您的应用程序,您可以保持原样并继续使用 JavaScript Fetch API,在标头中传递

Authorization
。例如:

from fastapi import Header

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

此外,请注意,您实际上不必在端点中定义任何

Header
参数,因为您始终可以通过
Request
对象直接访问它们,例如:

from fastapi import Request

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

解决方案 2

如果您确实也需要它与 Swagger UI 一起使用,一种解决方案是使用 FastAPI 的

HTTPBearer
,这将允许您在 Swagger 中单击屏幕右上角的
Authorize
按钮UI autodocs(位于
/docs
),您可以在其中的
Value
字段中键入您的API 密钥。这将在请求标头中设置
Authorization
标头。例子:

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

或者,您可以使用

APIKeyHeader
.

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 

解决方案 3

另一种解决方案是将

authorization
Header
参数重命名为其他名称,例如
token
。然后,在您的端点内,检查 API 密钥是否在
token
request.headers.get('Authorization')
参数中——如果两者都返回
None
,则这意味着没有提供令牌。例子:

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  
最新问题
© www.soinside.com 2019 - 2024. All rights reserved.