如何使用Cognito返回的代码获取AWS凭据?

arj*_*bar 12 javascript amazon-web-services amazon-cognito aws-sdk aws-cognito

现在,我正在努力了解AWS Cognito所以也许有人可以帮助我.我设置了一个域来为我的用户池提供Cognito的托管UI,就像这里描述的那样.因此,当我访问时,https://<my-domain>.auth.us-east-1.amazoncognito.com/login?response_type=code&client_id=<MY_POOL_CLIENT_ID>&redirect_uri=https://localhost:8080我会看到一个登录页面,我的用户可以通过Google登录我的应用程序.那部分工作得很好.

我很困惑在用户登录后如何处理从该页面返回的代码.因此,一旦我被重定向到Google并授权应用程序查看我的信息,我将被重定向回我的一个URL并带有代码查询参数.现在我正在重定向到localhost,因此重定向URL如下所示:

https://localhost:8080/?code=XXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX

这段代码究竟是什么?另外,如何使用它来为我的用户访问AWS资源?

bub*_*uro 20

首先,将身份验证拧紧一千次。没有人值得花半天时间看这玩意儿。

使用 Cognito 授权的 API 网关的身份验证

原料

  1. client_idclient_secret:在 Cognito > General Settings > App clients 中,您可以找到 App client id,然后单击 Show Details 找到 App client secret

  2. 对于标头,Authorization: Basic YWJjZGVmZzpvMWZjb28zc...您需要使用: 对这两个进行编码Base64Encode(client_id:client_secret),例如在 Python 中:

    import base64  
    base64.b64encode('qcbstohg3o:alksjdlkjdasdksd')`  
    
    Run Code Online (Sandbox Code Playgroud)

    旁注:Postman 还可以选择在 Authorization > Basic Auth 中生成它

  3. redirect_uri: 传入body,是你在App集成>App客户端设置中配置的回调url。
    这必须与您配置的内容相匹配,否则您将收到完全无用的消息{ "error": "invalid_grant" }

从代码中获取令牌的请求示例:

curl --location --request POST 'https://mycognitodomain.auth.us-east-1.amazoncognito.com/oauth2/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--header 'Authorization: Basic <base64 encoded client_id:client_secret>' \
--data-urlencode 'grant_type=authorization_code' \
--data-urlencode 'client_id=<client_id>' \
--data-urlencode 'code=<use the code you received post login>' \
--data-urlencode 'redirect_uri=https://myapp.com'
Run Code Online (Sandbox Code Playgroud)

这将返回您的令牌:

{
  "access_token":"eyJz9sdfsdfsdfsd", 
  "refresh_token":"dn43ud8uj32nk2je",
  "id_token":"dmcxd329ujdmkemkd349r",
  "token_type":"Bearer", 
  "expires_in":3600
}
Run Code Online (Sandbox Code Playgroud)

然后使用id_token并插入您的 API 调用:

curl --location --request GET 'https://myapigateway.execute-api.us-east-1.amazonaws.com/' \
--header 'Authorization: <id_token>'
Run Code Online (Sandbox Code Playgroud)

好的,这被标记为 JavaScript 但因为我们也在 Python 中受苦

友情提示:这是一个例子,请不要硬编码你的秘密。

import base64  
base64.b64encode('qcbstohg3o:alksjdlkjdasdksd')`  
Run Code Online (Sandbox Code Playgroud)

  • 超级清晰的解释。原始手册中令人困惑的部分是如何在步骤 #2 中构建授权。 (2认同)
  • 非常干净清晰的答案。我有点困惑“&lt;使用您登录后收到的代码&gt;”来自哪里?我猜这来自第一次重定向到“服务器”端,然后使用以下内容。(即 https://&lt;your_domain&gt;.auth.us-east-2.amazoncognito.com/login?response_type=code&amp;client_id=&lt;client_id&gt;&amp;redirect_uri=&lt;redirect_uri_server&gt;) (2认同)
  • 还有一个问题:如果您在应用程序客户端设置中配置了多个回调 uri,那么您在 /oauth2/token 请求中用作redirect_uri 的那个似乎必须与您最初用于获取授权代码的那个相匹配。 (2认同)

小智 6

要从授权代码oath2流返回的代码请求参数中获取AWS凭据(id_token,access_token和refresh_token),您应该使用您的Cognito用户池Web域/oauth2/token端点,请访问https://docs.aws.amazon.com/cognito/最新/ developerguide/token-endpoint.html说明.

注意HTTP基本验证用户名和密码的指令,它应该是你的Cognito应用程序client_idclient_secret,否则,你会得到一个invalid_client错误.

代码流应该在服务器端使用,因为您可以避免在URL上浮动的令牌.如果您计划执行该客户端,则应使用response_type=token,因为它直接在登录重定向上提供此结果.


ASR*_*ASR 5

不确定这是否会在被询问后的 10 个月内有用,但可能对其他人有帮助。

我已经使用response_type=token(Oauth flow= implicit grant& scope= openid) & provider as Cognito. 使用默认登录页面登录后,您将获得一个id_token& access_token。您可以使用 this 为您的用户获取临时身份id_token。您还需要为此设置一个联合身份池,为经过身份验证和未经身份验证的用户分配角色,并链接到您进行身份验证的用户池。一旦你有了它(假设你使用的是 javascript),你可以按照Cognito 用户身份池 javascript 示例中的示例进行操作。我的示例代码来自相同的 -

function getAccessToken(idToken, identityPoolId, userPool) {
        let provider = "cognito-idp.us-east-2.amazonaws.com/" + userPool;
        let login = {};

        login[provider] = idToken;

        // Add the User's Id Token to the Cognito credentials login map.
        let credentials = new AWS.CognitoIdentityCredentials({
            IdentityPoolId: identityPoolId,
            Logins: login
        });

        //call refresh method in order to authenticate user and get new temp credentials
        credentials.get((error) => {
            if (error) {
                console.error(error);

                let response = {
                    statusCode: 500,
                    body: JSON.stringify(error)
                };

                return response;

            } else {
                console.log('Successfully logged!');
                console.log('AKI:'+ credentials.accessKeyId);
                console.log('AKS:'+ credentials.secretAccessKey);
                console.log('token:' + credentials.sessionToken);

                let response = {
                    statusCode: 200,
                    body: JSON.stringify({
                        'AKI': credentials.accessKeyId,
                        'AKS': credentials.secretAccessKey,
                        'token': credentials.sessionToken
                    })
                };

                return response;
            }
        });
    }
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助。