【问题标题】:How to send Authorization Header through Swagger UI using FastAPI?如何使用 FastAPI 通过 Swagger UI 发送授权标头?
【发布时间】:2022-11-08 13:17:20
【问题描述】:

在前端,我有这个功能:

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'

但不断抛出以下错误:

在前端:

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

在后端:

POST /api/queue/upload_form_data/ HTTP/1.1" 400 Bad Request

在 Swagger UI(响应正文)中:

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

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

【问题讨论】:

  • 422 错误的正文将准确地告诉您缺少什么值以及请求失败的原因;在网络下查看浏览器的开发工具,以查看发送到服务器的实际请求(以及带有正文的响应)。

标签: python reactjs swagger swagger-ui fastapi


【解决方案1】:

在 Swagger/OpenAPI 规范中,Authorization 是保留的标头,还有 AcceptContent-Type 标头——参见 Swagger documentation——了解 Swagger 的内置 authentication/authorization 功能;因此,不允许定义它们。如果您使用的是 Swagger,则不能在端点参数中定义它,因为通过 Swagger 提交请求时它将被忽略,并且您将收到 422 Unprocessable Entity 错误,正文消息指出 authorization标头是错误的(就像您问题中发布的错误一样)。

解决方案

如果您不需要 Swagger 来测试您的应用程序,您可以保持原样并继续使用 JavaScript Fetch API,在标头中传递 Authorization。另外,请注意,您实际上不必在端点中定义任何标头,因为您始终可以通过 Request 对象访问它们,例如:

from fastapi import Request

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

如果您确实也需要通过 Swagger 进行此操作,一种解决方案是将 authorization 标头重命名为其他名称,例如 token,并在端点内部检查 API 密钥是否位于 token 或 @ 987654337@。否则,请使用 FastAPI 的 HTTPBearer,这将允许您在 /docs 的 Swagger UI 自动文档中单击屏幕右上角的 Authorize 按钮,您可以在 Value 中键入您的 API 密钥场地。这将在请求标头中设置 Authorization 标头。例子:

from fastapi.security import HTTPBearer

security = HTTPBearer()

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

或者,您可以使用APIKeyHeader

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

api_key = APIKeyHeader(name='Authorization')

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

【讨论】:

    猜你喜欢
    • 2020-10-23
    • 2015-08-01
    • 2022-10-16
    • 2020-01-06
    • 1970-01-01
    • 1970-01-01
    • 2023-02-23
    • 1970-01-01
    • 2017-10-29
    相关资源
    最近更新 更多