Amazon Cognito、IDプールの用途についての一考察

こんにちは。

　日頃、仕事でAWSのサービスを用い、自社内の開発/検証担当者向けにその環境を自作、共有できる基盤を作って提供する業務を行っている者です。
　またその延長線として、AWSのサーバレスの使い方について、ブログで紹介などもしております。

　本日は、そんな中で「Amazon Cognito」の「IDプール」について紹介しようと思い、記述致しました。

　「Amazon Cognito」（<a href="https://aws.amazon.com/jp/cognito/">https://aws.amazon.com/jp/cognito/</a>）の機能は、大きく2つに分かれています。

・ユーザープール：認証ユーザを管理する（プールしておく）機能を持つ。これをベースに独自の認証を行うことができる。

・IDプール：認証されたユーザに対して、AWS上のサービスの利用権限を付与する機能を持つ。認証には、ユーザープールの他、facebook等、外部の認証も使用できる。

　IDプールの設定方法自体については、AWSの公式ページなどにお任せし、ここでは省かせて頂きます。
<a href="https://docs.aws.amazon.com/ja_jp/cognito/latest/developerguide/identity-pools.html">https://docs.aws.amazon.com/ja_jp/cognito/latest/developerguide/identity-pools.html</a>

　使い方自体も非常にシンプルで、例えば、ユーザープールで認証されたユーザにAWSのEC2のインスタンスリストを返すLambda関数を書けば、こんな感じになります。
<pre><code>var async = require('async');
const AWS = require('aws-sdk');
AWS.config.loadFromPath('&lt;AWSの設定ファイルパス&gt;');
var cgn = new AWS.CognitoIdentity();

const poolId = "&lt;ユーザープールID&gt;";
const IdPoolId = "&lt;IDプールID&gt;";
const regionStr = "ap-northeast-1";  // 取り敢えず東京リージョンで書いておきます
const accessUrl = "cognito-idp." + regionStr + ".amazonaws.com/" + poolId;  // 認証URL

exports.handler = function(event, context, _callback) {
    var inData = JSON.parse(event.body);  // LambdaにPostで渡された引数をJSONの変数として保持
    async.waterfall([
        (next) =&gt; {
            // ユーザープールIDとトークンを用いてIDの取得
            var params = {
                IdentityPoolId: IdPoolId,
                Logins: {
                    [accessUrl]: inData.token  // Lambdaに渡された変数内のToken
                }
            };
            cgn.getId(params, function(err, data) {
                next(err, data);
            });
        },
        (data, next) =&gt; {
            <span style="color: #ff6600;">// IDとトークンを用いて一時的な認証の取得</span>
            var params = {
                IdentityId: data.IdentityId,
                Logins: {
                    "cognito-idp.ap-northeast-1.amazonaws.com/ap-northeast-1_&lt;hogehoge&amp;gt": inData.token
                }
            };
            cgn.getCredentialsForIdentity(params, function(err, data) {
                next(err, data);
            });
        },
        (data, next) =&gt; {
            var ec2 = new AWS.EC2({        <span style="color: #ff6600;">// 一時的な認証を用いて作成</span>
                "accessKeyId": data.Credentials.AccessKeyId,
                "secretAccessKey": data.Credentials.SecretKey,
                "sessionToken": data.Credentials.SessionToken,
                "region": regionStr
            };
            var params = {};
            ec2.describeInstances(params, function(err, data) {
                if (err) {
                    next(err, err);
                } else {
                    next(null, data);
                }
            });
        }
    ],
    (err, data) =&gt; {
        _callback(err, data);
    });
};</code></pre>
　…ですが、上の例のように「Amazon Cognito」の「ユーザープール」に定義されたユーザであれば、登録段階で権限制御できるので、「IDプール」のように「一時的な権限」を振り出す必要はありません。
　つまり、「IDプール」が真価を発揮するのは<strong>「facebookなど、AWS以外の（認証済み）ユーザへのサービスをAWSを用いて追加/機能拡張する」</strong>というケースになるかと存じます。
※上記例では「ユーザープールIDとトークンを用いてIDの取得」の部分を、facebookなどの外部サービスを用いた場合のものに変更する必要がでてきます。

　（そういう意味では、<strong>「Amazon Cognito」の「IDプール」は、「ユーザープール」を使わない人こそ使うべき機能</strong>という気もしてきます。）


　以上、最後の数行でこの記事の本論を書いた形になり恐縮ですが、皆さまのシステム開発の何がしかのヒントにでもなりましたら幸いです。