web-dev-qa-db-ja.com

CognitoホストUI

クライアントがS3でホストされたデータを表示できるようにするWebアプリのログインの設定を検討しており、AWS CognitoにはホストされたWeb UIがあることがわかりました [link] はほとんどの認証フローを処理します、私が直面している問題は、Web UIの出力をアプリに統合する方法を見つけることができないことです。 Cognitoの既存のドキュメントのほとんどは、独自のUIを作成する際にさまざまなAPIを使用する方法を参照しているだけであり、私の問題に対する混乱した答えを残しています。

CognitoホストUIを念頭に置いて作成された情報はありますか?

Amazonは、認証されたログインをCognitoと数分で統合できると言っていますが、私はこれを数週間見ていて、理解できませんでした。

30
Fyreye

私もこれに苦労しました。ドキュメントが少し軽いことに同意します。

指定したリンクは、Cognito UI URLがどのように見えるかを示しています。

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

このURIにユーザーを送信し、彼らがビジネスを行った後、何らかのトークンまたはコードを使用してユーザーをリダイレクトします。左のナビゲーションバーの[ドメイン名]をクリックして、ドメインを確認できます。

App Client SettingsおよびOAuth Grant Types

まず、アプリクライアントの設定を確認します。コールバックURL(Cognitoのリダイレクト先)をホワイトリストに登録し、少なくとも1つのOAuthフローが許可されていることを確認する必要があります。

Cognitoアプリクライアント設定

「承認コードの付与」は承認コードを返し、それを_oauth2/token_エンドポイントに送信して、access_token、id_token、およびrefresh_tokenを取得します。これは、バックエンドアプリケーションがあり、更新トークンが必要な場合に適しています。

「暗黙的な付与」は、フロントエンドアプリケーションで使用しているものです。これは、アクセストークンとIDトークンをフロントエンドアプリに直接返します。

暗黙的な許可を使用するには、Cognito UI URLで_response_type=code_を_response_type=token_に変更します。

暗黙的付与の例

したがって、認証成功後のリダイレクトが次のようになっている場合:

_https://localhost:3000/#access_token=eyJraWQiOiJG...&id_token=eyJraWQZNg....&token_type=Bearer&expires_in=3600
_

ログインマップのキーとしてユーザープールを使用して、URLからid_tokenを剥がしてCognitoに送信するだけです。 Javascriptの場合:

_AWS.config.credentials = new AWS.CognitoIdentityCredentials({
    IdentityPoolId: 'us-east-1:bxxxxxx6-cxxx-4xxx-8xxx-xxxxxxxxxx3c',
    Logins: {
        'cognito-idp.us-east-1.amazonaws.com/us-east-1_ixxxxxxx': idToken
    }
});
_

ここで、idTokenは、リダイレクトで返されたIDトークンです。

認証コード付与タイプ

代わりに認証コード付与タイプを使用する場合(response_type = code)、バックエンドは_/oauth2/token_エンドポイントを呼び出してトークンのコードを交換する必要があります。その呼び出しは次のようになります。

_curl -X POST \
  https://<my-cognito-domain>.auth.us-east-1.amazoncognito.com/oauth2/token \
  -H 'content-type: application/x-www-form-urlencoded' \
  -d 'grant_type=authorization_code&scope=email%20openid%20profile&redirect_uri=https%3A%2F%2Flocalhost%3A3000%2F&client_id=15xxxxxxxxxxxxxx810&code=54826355-b36e-4c8e-897c-d53d37869ee2'
_

次に、このIDトークンを上記のようにCognitoに渡すことができます。

UIノート

ユーザーがリンクをクリックすると、アプリケーションがCognito UIを新しいタブにポップアップします。リダイレクトがアプリに戻ってきたら、postMessage()を使用してトークンを親ウィンドウに送信します。これにより、新しいタブが閉じられます。これは比較的一般的なパターンだと思います。

試したことはありませんが、クリックジャッキングを軽減するために、UIをiframeにレンダリングすることは許可されていないと思います。 ソース


これが少なくともいくらか役立つことを願っています。幸運を!

63
Mike Patrick

Cognito Hosted UIを使用して、Amplifyを使用せずにこのフローを実装しました。

  1. ユーザーが私のWebサイト(タブ1)をナビゲートし、任意のページでユーザーがログイン/登録ボタンをクリックします。
  2. 新しいタブ(タブ2)が開き、自分のドメイン(auth.example.com)を使用してCognitoホストUIが開きます
  3. 次に、ユーザーはホストされたUIでビジネスを行います(ログイン/新しいアカウント/パスワードの回復など)
  4. Cognitoは、多くのトークンを含むHASHをサイトコールバックに送信します。( https://example.com/login
  5. 私のサイトはトークンを処理します:トリックはAuthインスタンスを作成することです。これはハッシュを解析し、LocalStorageにユーザーを作成できます:

    // mysite.com/login 
    import {CognitoAuth} from 'Amazon-cognito-auth-js';
    
    // Configuration for Auth instance.
    var authData = {
        UserPoolId: 'us-east-1_xxxx',
        ClientId: '1vxxxxx',
        RedirectUriSignIn : 'https://example.com/login',
        RedirectUriSignOut : 'https://example.com/logout',
        AppWebDomain : 'example.com',
        TokenScopesArray: ['email']
        };
    var auth = new CognitoAuth(authData);
    
    //Callbacks, you must declare, but can be empty. 
    auth.userhandler = {
        onSuccess: function(result) {
    
        },
        onFailure: function(err) {
        }
    };
    
    //Get the full url with the hash data.
    var curUrl = window.location.href;
    
    
    //here is the trick, this step configure the LocalStorage with the user.
    auth.parseCognitoWebResponse(curUrl);
    window.top.close();
    
  6. ユーザーがローカルストレージに設定された後、コールバック(タブ2)は閉じられます。

  7. 私のサイト(タブ1)では、ローカルストレージに変更がある場合にリッスンするようにEventListenerを構成します。

          constructor() {
          window.addEventListener('storage', this.userLogged);
          }
    
          userLogged(event) {
    
            if (event.key.indexOf('CognitoIdentityServiceProvider') !== -1) {
    
              var data = {
                          UserPoolId: 'us-east-1_xxxxx',
                          ClientId: 'xxxxx'
                          };
    
             var userPool = new CognitoUserPool(data);
    
             //behind the scene getCurrentUser looks for the user on the local storage. 
             var cognitoUser = userPool.getCurrentUser();
                }
           }
    
  8. 資格情報またはその他のデータを取得できるため、cognitoUserで完了です。
1