【问题标题】:FastApi 422 Unprocessable Entity, on authentication, how to fix?FastApi 422 Unprocessable Entity,关于身份验证,如何解决?
【发布时间】:2021-05-10 11:08:23
【问题描述】:

无法理解,即使我删除了所有内部函数并仅打印某些内容仍然出现此错误,但是当我使用 fastapi 文档并尝试使用该文档进行签名时,它可以工作。

@auth_router.post('/signin')
async def sign_in(username: str = Form(...), password: str = Form(...)) -> dict:
    user = await authenticate_user(username, password)

    if not user:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED, 
            detail='Invalid username or password',
        )

    user_obj = await User_Pydantic.from_tortoise_orm(user)
    user_token = await generate_token(user_obj)

    return {
        'access_token': user_token,
        'token_type': 'bearer',
    }

在我使用 OAuth2PasswordRequestForm 之前,遇到 422 错误,请尝试其他方式。

我的模型是乌龟 orm,需要时我将其转换为 pydantic 模型, 在文档中一切正常。

JS

handleEvent(signinform, 'submit', e => {
    e.preventDefault();
    if(!isEmpty(signinform)){

        signInUsername = getElement('input[name="username"]', signinform).value;
        signInPassword = getElement('input[name="password"]', signinform).value;
        recaptchaV3 = getElement('[name="g-recaptcha-response"]').value;

        if(recaptchaV3){
            signInData = new FormData();
            signInData.append('username', signInUsername);
            signInData.append('password', signInPassword);

            isLogened = request('POST', '/signin', signInData);
            if(isLogened){
                log(isLogened);
            }
            
        } else{
            alert('Reload Page');
        }

    }

})

authenticate_user 函数

async def authenticate_user(username: str, password: str):
    user = await User.get(username=username)

    if not user or not user.verify_password(password):
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED, 
            detail='Invalid username or password',
        )
    return user

我的请求函数

const request = (method, url, data = null) => {
    return new Promise((resolve, reject) => {
        let xhr = new XMLHttpRequest()
        xhr.open(method, url, true)
        xhr.setRequestHeader('Content-Type', 'application/json')
        xhr.onerror = function () {
            console.log(xhr.response);
        };
        xhr.onload = () => {
        if (xhr.status === 200) {
            return resolve(JSON.parse(xhr.responseText || '{}'))
            } else {
                return reject(new Error(`Request failed with status ${xhr.status}`))
            }
        } 
        if (data) {
            xhr.send(JSON.stringify(data))
        } else {
            xhr.send()
        }


    })
}

【问题讨论】:

  • 422 错误的正文将解释缺少哪些预期信息。 422 表示缺少 FastAPI 端点所需的参数之一(即它与预期的输入格式不匹配)。该消息将告诉您哪些字段丢失/在错误的位置。可能的解释是您包含了端点不期望的recaptcha 值(如果您使用文档,则不会期望)。不过,不确定这是否会导致 422 错误。
  • @MatsLindh 不,我尝试 recaptcha 没有引发错误,我的身体是空的,我更新我的问题,添加我如何发送请求的功能
  • 您将数据作为 JSON 发送,但您使用 Form(...) 作为参数 - 这意味着常规的 urlencoded 后参数。

标签: javascript python fastapi


【解决方案1】:

虽然你没有发布错误,但谁的目的是告诉你问题,我相当确定问题在于你执行请求的方式。

线

xhr.setRequestHeader('Content-Type', 'application/json')

表示你发送的是json数据,openapi的认证形式不接受。此外,您正在将数据字符串化为 json,这又不是一种可接受的格式。

因此,将内容类型更改为 www-form-urlencoded 并将 FormData 对象添加到您的请求正文中,将使其工作。

你可以在下面的 github 讨论中看到它

https://github.com/tiangolo/fastapi/issues/2740 https://github.com/tiangolo/fastapi/issues/1431

【讨论】:

  • 是的,问题出在它里面,抱歉只是盲目复制 js 代码,从一件事到另一件事,我删除了那行并且它工作,我尝试将请求标头设置为你建议我的内容,并尝试使用 multipart/form-data 并且不起作用,但删除该行是可行的想法! TNX 很多先生。
猜你喜欢
  • 2021-12-19
  • 2022-08-14
  • 1970-01-01
  • 2022-11-08
  • 2019-04-26
  • 2023-01-07
  • 2021-02-06
  • 1970-01-01
  • 2021-06-24
相关资源
最近更新 更多