簡體   English   中英

如何使用從 Cognito 返回的代碼來獲取 AWS 憑證?

[英]How to use the code returned from Cognito to get AWS credentials?

現在,我正在努力理解 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 資源?

首先,將身份驗證擰緊一千次。 沒有人值得花半天時間看這玩意兒。

使用 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')`

    旁注: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'

這將返回您的令牌:

{
  "access_token":"eyJz9sdfsdfsdfsd", 
  "refresh_token":"dn43ud8uj32nk2je",
  "id_token":"dmcxd329ujdmkemkd349r",
  "token_type":"Bearer", 
  "expires_in":3600
}

然后獲取id_token並插入您的 API 調用:

curl --location --request GET 'https://myapigateway.execute-api.us-east-1.amazonaws.com/' \
--header 'Authorization: <id_token>'

好的,這被標記為 JavaScript 但因為我們也在 Python 中受苦

友情提示:這是一個例子,請不要硬編碼你的秘密。

import requests

# In: General Settings > App clients > Show details
client_id = "ksjahdskaLAJS ..."
client_secret = "dssaKJHSAKJHDSsjdhksjHSKJDskdjhsa..."

# URL in your application that receives the code post-authentication
# (Cognito lets you use localhost for testing purposes)
callback_uri = "http://localhost:8001/accounts/amazon-cognito/login/callback/"

# Find this in: App Integration > Domain
cognito_app_url = "https://my-application-name.auth.us-west-2.amazoncognito.com"

# this is the response code you received - you can get a code to test by going to
# going to App Integration > App client settings > Lunch Hosted UI
# and doing the login steps, even if it redirects you to an invalid URL after login
# you can see the code in the querystring, for example:
# http://localhost:8001/accounts/amazon-cognito/login/callback/?code=b2ca649e-b34a-44a7-be1a-121882e27fe6
code="b2ca649e-b34a-44a7-be1a-121882e27fe6"

token_url = f"{cognito_app_url}/oauth2/token"
auth = requests.auth.HTTPBasicAuth(client_id, client_secret)

params = {
    "grant_type": "authorization_code",
    "client_id": client_id,
    "code": code,
    "redirect_uri": callback_uri
}

response = requests.post(token_url, auth=auth, data=params)

print(response.json()) # don't judge me, this is an example

要從授權代碼 oath2 流返回的代碼請求參數中獲取 AWS 憑證(id_token、access_token 和 refresh_token),您應該使用您的 Cognito 用戶池網絡域/oauth2/token端點,遵循https://docs.aws.amazon。 com/cognito/latest/developerguide/token-endpoint.html說明。

注意 HTTP 基本授權用戶和密碼說明,應該是你的 Cognito App client_idclient_secret ,否則,你會得到一個invalid_client錯誤。

代碼流應該在服務器端使用,因為您可以避免令牌在 URL 上浮動。 如果你打算做那個客戶端,你應該使用response_type=token ,因為它直接在登錄重定向上給出這個結果。

不確定這是否會在被詢問后的 10 個月內有用,但可能對其他人有幫助。

我使用response_type=token (Oauth flow= implicit grant & scope= openid ) & provider 作為Cognito 使用默認登錄頁面登錄后,您將獲得id_tokenaccess_token 您可以使用此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;
            }
        });
    }

希望這會有所幫助。

簡單地說,您可以使用代碼和 Cognito clientId+hostname 請求 id/access/refresh 令牌,然后使用 id 和訪問令牌來識別 API 調用中的用戶。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM