【问题标题】:How programtically exchange the authorization code to get the access token from cognito using python如何使用 python 以编程方式交换授权代码以从 cognito 获取访问令牌
【发布时间】:2025-11-30 22:35:01
【问题描述】:

我一直在寻找有关如何交换授权码以务实地从 cognito 获取访问令牌的解决方案。我已经创建了认知池和集成的应用程序客户端。因此,当我以以下格式调用登录域时,我将获得登录页面并能够登录/注册

https://<your_domain>/login?response_type=code&client_id=<your_app_client_id>&redirect_uri=<your_callback_url>

现在上面的url将返回authorization_code作为参数。我使用 post man 通过以下查询获取结果,该查询返回 id 令牌、访问令牌、刷新令牌。

POST https://mydomain.auth.us-east-1.amazoncognito.com/oauth2/token&
Content-Type='application/x-www-form-urlencoded'
grant_type=authorization_code&
client_id=myid&
code=AUTHORIZATION_CODE&
redirect_uri=http://localhost:5000/login

现在我需要在我的应用中实现相同的功能以获取访问令牌 下面是我试过的代码

 response = requests.post(url + '/oauth2/token',
                             auth=(App_client_id),
                             data={'grant_type': grant_type, 'code': accessCode, 'client_id': App_client_id,
                                   "redirect_uri":'http://localhost:5000/login'})
print(response.json())

但我没有得到任何回应。

预期:我正在寻找如何实现以下用例

  1. 我有一个 api-gatway 与 cognito userpool/authorizer 相关联,并且此 api-gateway 从其他 aws 服务(例如 lambda)返回响应。

2.在我的应用程序 - Flask 应用程序中,我想以这样一种方式放置一个逻辑,即一旦用户在登录后通过用户池进行身份验证,它就会在 redirect_uri 中返回授权码。

  1. 在redirect_uri 中,我有某些操作-读/写/删除任务。对于每个任务,我需要使用通过授权码交换接收到的访问令牌进行身份验证。所以只有登录的用户才能从重定向 uri 进行操作。

是否有人可以帮助解决此问题?

谢谢

【问题讨论】:

  • 你是否在请求中添加了包含clientId + ":" + secret的Base64编码结果的授权头?
  • 嗨@HenriqueDroog,我只添加了文档docs.aws.amazon.com/cognito/latest/developerguide/…中建议的客户端ID,它建议将客户端ID作为其“授权代码授予”类型传递
  • 我相信只有 clientId 而不是 Base64 编码是行不通的。我相信 clientID 和 secret mis 都可以用来获取 Base64 编码,就像授权部分提到的 docs.aws.amazon.com/cognito/latest/developerguide/… 一样。但是,如果您的客户没有获得秘密,我不确定会怎样。
  • 嗨@HenriqueDroog ..我已经更新了我期待实施的预期用例的问题。正如我所提到的,我可以使用具有上述参数的 POST 人获取令牌。而且我不是在寻找我不想在响应中公开令牌的“隐式授予”类型。如果在这种情况下我的方法有误,请纠正我。谢谢

标签: python-3.x api oauth-2.0 amazon-cognito


【解决方案1】:

您提到您在 POSTMAN 中实现了此功能,但在 Python 代码中却没有。因此,您需要确保将 POSTMAN 中的请求中的所有内容复制到脚本中的请求中。

例如,您是否在 Python 请求中将 Content Type 标头设置为 Content-Type='application/x-www-form-urlencoded'。我不相信。

此外,如果您没有与 Cognito 应用程序客户端关联的应用程序客户端密码,则不会发送授权标头。我对请求库不太熟悉,但我认为您不需要以下 'auth=(App_client_id),'。

https://docs.aws.amazon.com/cognito/latest/developerguide/token-endpoint.html

如果给客户端发了一个秘密,客户端必须通过 其在授权标头中的 client_id 和 client_secret 通过 基本 HTTP 授权。秘诀是基本 Base64Encode(client_id:client_secret)。

【讨论】:

  • 嗨@callo,我终于得到了答案。如果您有任何建议,请告诉我。谢谢
【解决方案2】:

Finlay 获得了交换授权码的方法,以使用以下代码从 cognito auth 检索 access_token 以及刷新和 id_token:

response = requests.post(url + '/oauth2/token',{'Content-Type':'application/x-www-form-urlencoded', 'grant_type': grant_type, 'client_id': App_client_id,  'code': code, 'redirect_uri': 'http://localhost:5000/login'})
print(response.json())

谢谢

【讨论】:

  • 你如何得到code ? - 编辑:交互,如果我理解你的问题。
【解决方案3】:

对于其他坚持让它工作的人,我发现它使用 requests.post 中的 params 参数工作

token_url="https://myapp.auth.us-east-1.amazoncognito.com/oauth2/token"
message = bytes(f"{client_id}:{client_secret}",'utf-8')
secret_hash = base64.b64encode(message).decode()
payload = {
    "grant_type": 'authorization_code',
    "client_id": client_id,
    "code": code,
    "redirect_uri": redirect_uri
}
headers = {"Content-Type": "application/x-www-form-urlencoded",
            "Authorization": f"Basic {secret_hash}"}
           
resp = requests.post(token_url, params=payload, headers=headers)

【讨论】:

  • 这对我也有用,非常感谢。作为“请求”的新手,我可能会补充一点,在上面的这种情况下,令牌的输出不是 resp,而是 resp.text。我为此挂了几个小时。 resp 只是状态。 ug :) 输出 resp.text 后看到 token 出现在屏幕上就像是眼睛的美味。
最近更新 更多