【问题标题】:How do I post Form Data with aiohttp?如何使用 aiohttp 发布表单数据?
【发布时间】:2022-01-30 03:39:39
【问题描述】:

我正在测试使用 FastAPI 制作 OAuth 服务器。我有一侧,即 Oauth 服务器,它的端点如下所示:

@router.post("/token")
async def login_for_access_token(form_data: OAuth2PasswordRequestForm = Depends()) -> Dict[str, str]:
    return {"access_token": form_data.username, "token_type": "bearer"}

然后在一个单独的进程中,我有一个带有登录端点的假应用程序,如下所示:

@router.post("/")
async def login(username: str, password: str) -> Dict[str, str]:

    form = OAuth2PasswordRequestForm(
        username=username,
        password=password,
        scope="me"
    )

    form_data = aiohttp.FormData()

    for key, val in form.__dict__.items():
        form_data.add_field(key, val)

    async with aiohttp.ClientSession() as session:
        async with session.post(f"http://localhost:8001/oauth/token", data=form_data()) as server_response:
            response = await server_response.text()
            response = json.loads(response)
    return response

OAuth 服务器正在响应

{
  "detail": [
    {
      "loc": [
        "body",
        "grant_type"
      ],
      "msg": "string does not match regex \"password\"",
      "type": "value_error.str.regex",
      "ctx": {
        "pattern": "password"
      }
    }
  ]
}

如何使用 aiohttp 将表单数据发布到 oauth 服务器?

【问题讨论】:

  • 它抱怨表单数据不包括grant_type 键值password;您发送的数据中似乎没有包含一个?

标签: python oauth-2.0 fastapi aiohttp


【解决方案1】:

您的数据中缺少 grant_type 字段。尽管grant_type 是一个可选字段,但根据documentation(请查看“提示”部分):

OAuth2 规范实际上需要一个字段 grant_type 和一个固定的 password 的值,但 OAuth2PasswordRequestForm 不强制执行它。

如果您需要强制执行,请改用 OAuth2PasswordRequestFormStrict OAuth2PasswordRequestForm。

因此,您的表单应如下所示。 grant_type="password" 表示您正在向/token 端点发送用户名和密码(也请查看this answer)。

form = OAuth2PasswordRequestForm(
    grant_type="password",
    username=username,
    password=password,
    scope="me"
)

【讨论】:

    猜你喜欢
    • 2022-12-15
    • 2018-12-25
    • 2021-02-16
    • 2016-11-17
    • 2018-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多