Amazon CognitoをJavaScriptから使ってみる

[Amazon Congnito](http://aws.typepad.com/aws_japan/amazon-cognito/)を用いてAWS認証情報を一時的に取得して、適切なアクセス制限をかけたいと思います。スマホやデバイスからAmazon S3やAmazon DynamoDBやAmazon Kinesisにデータをあげていく際に、クレデンシャルをクライアント側にあまり置きたくないので、Cognitoを使うことにします。

# Amazon Cognitoとは
CognitoはAWSを用いたスマホのアプリ開発をより簡単にするためのユーザの認証やデバイス感のデータの同期を簡単に実現するためのサービスです。Amazon、Facebook、Google といったパブリックログインプロバイダを使用して認証できますが、ここでは、パブリックログインプロバイダを使わずにCognitoのゲストアクセスの機能を用いて、アクセス制限のためのみに使います。つまり、アプリケーションに認証情報をハードコーディングする必要はなくなるので、セキュリティのベストプラクティスに従って、権限の制限された一時的な認証情報を使用できます。

# Amazon Cognitoのアイデンティティプールを作成する

では早速Amazon Cognitoのマネージメントコンソールにアクセスします。現在は、US-EASTリージョンとEUリージョンのみで使えるので今回はUS-EASTを使います(2014/11/20時点)。
![](https://dl.dropboxusercontent.com/u/2649297/2014-11-29_18-42-23.png)

アイデンティティプールの名前を指定。
![](https://dl.dropboxusercontent.com/u/2649297/2014-11-29_18-42-23_01.png)

ゲストアクセスを可能にするために、Unauthenticated IdentitiesをEnableします。
![](https://dl.dropboxusercontent.com/u/2649297/2014-11-29_18-42-25.png)

ここで自動的にIAM Roleが２個作られます。Authenticated用とUnauthenticated用。Authenticated用は今回は使いませんが、とりいそぎこのままUpdate。
![](https://dl.dropboxusercontent.com/u/2649297/2014-11-29_18-42-32.png)

# Amazon CognitoでJavaScriptからクレデンシャルを取得
ここでは、手元のPCからCognitoで認証できるかやってみましょう。[node.js環境](http://nodejs.jp/nodejs.org_ja/)とaws-sdk for javascriptが入っていない場合はインストールしてください。

```
$ npm install aws-sdk
```

下記のようなjsファイルを作成します。AccountID, RoleArn, IdentityPoolIdにご自身のものを入れるのに注意です。

```js:cognito.js

var AWS = require('aws-sdk');
var awsRegion = "us-east-1";
var cognitoParams = {
    AccountId: "41073212XXXX",
    RoleArn: "arn:aws:iam::41073212XXXX:role/Cognito_iot_hackUnauth_DefaultRole",
    IdentityPoolId: "us-east-1:8286c169-3ff5-4feb-aad9-9f7d9XXXXXXXXX"
};

AWS.config.region = awsRegion;
AWS.config.credentials = new AWS.CognitoIdentityCredentials(cognitoParams);
AWS.config.credentials.get(function(err) {
        if (!err) {
            console.log("Cognito Identity Id: " + AWS.config.credentials.identityId);
        }
});
```

実行します。すると下記のように、Cognito Identityがとれていることが分かります。これでAWSのリソースにアクセスできます。

```
$ node cognito.js
Cognito Identity Id: us-east-1:2908a57d-fe97-4b15-a0a9-03dbXXXXXXXX
```
簡単ですね！もちろんより厳密にするには、Facebook等のパブリックログインプロバイダと連携させる必要がありますが、開発者向けにある特定のリソースのみを解放するには使えるやり方です。

# ゲストアクセスにアクセスポリシーを割り当てる

さて、現状ですと、CognitoでゲストアクセスしてもCognito以外のAWSリソースにはアクセス出来ない状態です。ここで、[IAM](http://aws.amazon.com/jp/iam/)を用いて、Cognito_iot_hackUnauth_DefaultRoleのロールに対して必要なアクセスポリシーを付与します。

IAMのマネージメントコンソールからやってみましょう。Cognito_iot_hackUnauth_DefaultRoleを選択します。
![](https://dl.dropboxusercontent.com/u/2649297/2014-11-30_08-53-15.png)

ロールポリシーをアタッチしていきます。
![](https://dl.dropboxusercontent.com/u/2649297/2014-11-30_08-53-33.png)

必要なパーミッションを探します。Kinesisへの書き込みも含めたポリシーを付与してみましょう。
![](https://dl.dropboxusercontent.com/u/2649297/2014-11-30_08-53-50.png)

実際のポリシーはこんな感じです。ある特定のストリームのみ、といったこともやりたいかもしれません。もちろん、Kinesis以外にも複数のポリシーを付与できます。
![](https://dl.dropboxusercontent.com/u/2649297/2014-11-30_08-53-56.png)

ポリシーが付与されたことが確認できました。
![](https://dl.dropboxusercontent.com/u/2649297/2014-11-30_08-54-01.png)

これで、cognitoのゲストアクセスにKinesisのフルアクセス権限を加えることができました！

# さいごに所感
* デバイスからにしろスマホからにしろAWSのリソース(KinesisとかDynamoDB)をさわりにいくときに、Cognitoを使って認証するのはやはり良い。IAM Roleとの統合の感じも良いし、クレデンシャルを貼付けなくて良いのはセキュリティベストプラクティスに従っており、安心感がある。AWSリソースに対するアクセス制御は、CognitoのRoleに対して必要なポリシーを割り当てていくだけなので簡単。
* CongnitoでJavaScriptで認証して、そのままAWS SDK for JavaScriptでS3やらDynamoDBやらKinesisやらゴニョゴニョできるので楽。

免責
こちらは個人の意見で会社とは関係ありません。