この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
丹内です。Public Betaになってしばらく経つCognito UserPoolsですが、そのサンプルアプリを見つけたので動かして観察してみます。
Cognito UserPoolsとは
Amazon Cognitoは、モバイルアプリやSPA(Single Page Application)など信頼できない環境で動作するAWS SDKに対して、クレデンシャルの安全な発行を行うためのサービスです。ユーザ認証とクレデンシャル発行(Cognito Identity)、ユーザデータ管理(Cognito Sync)の機能を有しています。
そんなCognitoに先日追加された機能が、Cognito UserPoolsです。
[新機能] Amazon Cognito に待望のユーザー認証基盤「User Pools」が追加されました!
UserPools以前のCognito(Cognito Federated Identity)では、Authentication providersとしてOIDC IdPやSAMLを利用することができました。
UserPoolsによって、Authentication providersにCognitoが管理する、メールアドレスとパスワードにより認証されるIdentityも利用可能となりました。
大抵のアプリケーションではメールアドレスとパスワードで認証されるユーザ管理機能が付いていると思いますが、UserPoolsによりフルマネージドな機能が提供されます。さらに、クライアントにAWSリソースを操作するクレデンシャルを安全に付加することができるので、クライアントから直接AWSを操作することで、サーバ側の負荷を減らすことも行いやすくなります。
セットアップ
今回動かすサンプルアプリのリポジトリは以下になります。
awslabs/aws-cognito-angular2-quickstart
READMEに沿ってセットアップしていきます。
$ git clone --depth 1 git@github.com:awslabs/aws-cognito-angular2-quickstart.git
$ cd aws-cognito-angular2-quickstart
$ npm install
$ bower install
が、Macの場合はsedのオプションが異なるためAWSリソース作成スクリプトが動作しません。 そこで、シェルスクリプトを以下のdiffのように編集します。
diff --git a/aws/createResources.sh b/aws/createResources.sh
index b96b7ed..aa4f2bb 100755
--- a/aws/createResources.sh
+++ b/aws/createResources.sh
@@ -1,6 +1,11 @@
#!/usr/bin/env bash
-ROOT_NAME=DevDay
+if [ $# -ne 1 ]; then
+ echo "usage: createResources.sh [name]"
+ exit 1
+fi
+
+ROOT_NAME=$1
BUCKET_NAME=budilov-$ROOT_NAME
TABLE_NAME=LoginTrail$ROOT_NAME
ROLE_NAME_PREFIX=$ROOT_NAME
@@ -44,12 +49,12 @@ aws iam put-role-policy --role-name $ROLE_NAME_PREFIX-authenticated-role --polic
# Create the user pool
aws cognito-idp create-user-pool --pool-name $POOL_NAME --policies file://user-pool-policy.json --region $REGION > /tmp/$POOL_NAME-create-user-pool
-userPoolId=$(grep -Po '"Id":.*?[^\\]",' /tmp/$POOL_NAME-create-user-pool | awk -F'"' '{print $4}')
+userPoolId=$(perl -nle 'print $& if m{"Id":.*?[^\\]",}' /tmp/$POOL_NAME-create-user-pool | awk -F'"' '{print $4}')
echo "Created user pool with an id of " $userPoolId
# Create the user pool client
aws cognito-idp create-user-pool-client --user-pool-id $userPoolId --no-generate-secret --client-name webapp --region $REGION > /tmp/$POOL_NAME-create-user-pool-client
-userPoolClientId=$(grep -Po '"ClientId":.*?[^\\]",' /tmp/$POOL_NAME-create-user-pool-client | awk -F'"' '{print $4}')
+userPoolClientId=$(perl -nle 'print $& if m{"ClientId":.*?[^\\]",}' /tmp/$POOL_NAME-create-user-pool-client | awk -F'"' '{print $4}')
echo "Created user pool client with id of " $userPoolClientId
また、AWSアカウントIDも書き換えておく必要があります。
diff --git a/aws/authrole.json b/aws/authrole.json
index df27aeb..6806522 100644
--- a/aws/authrole.json
+++ b/aws/authrole.json
@@ -23,7 +23,7 @@
"dynamodb:DeleteItem"
],
"Resource": [
- "arn:aws:dynamodb:us-east-1:540403165297:table/TABLE_NAME"
+ "arn:aws:dynamodb:us-east-1:012345678901:table/TABLE_NAME"
],
"Condition": {
"ForAllValues:StringEquals": {
その上で、以下のように実行します。
$ aws/createResources.sh mycognitosample
READMEにも記載されていますが、シェルスクリプト実行時にCognito IdentityへのRoleの設定がエラーになってしまうので、リソース作成完了後に自分で設定する必要があります。
このシェルスクリプトで作成される主要なリソースは、以下のとおりです。us-east-1に作成されます。
- Cognito UserPool
- Cognito Federated Identity Pool
- DynamoDBテーブル(アクセスログ機能用、RCU1/WCU1、Estimated cost $0.59/month)
- IAMロール(authenticatedとunauthenticatedの2つ)
authenticated roleのポリシーは以下のとおりです。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"mobileanalytics:PutEvents",
"cognito-sync:*",
"cognito-identity:*"
],
"Resource": [
"*"
]
},
{
"Effect": "Allow",
"Action": [
"dynamodb:GetItem",
"dynamodb:BatchGetItem",
"dynamodb:Query",
"dynamodb:PutItem",
"dynamodb:UpdateItem",
"dynamodb:DeleteItem"
],
"Resource": [
"arn:aws:dynamodb:us-east-1:012345678:table/LoginTrailmycognitosample"
],
"Condition": {
"ForAllValues:StringEquals": {
"dynamodb:LeadingKeys": [
"${cognito-identity.amazonaws.com:sub}"
]
}
}
}
]
}
このIAMロールのTrust Relationshipは以下のとおりです。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "cognito-identity.amazonaws.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"cognito-identity.amazonaws.com:aud": "us-east-1:aaaa-bbbb-cccc-dddd"
},
"ForAnyValue:StringLike": {
"cognito-identity.amazonaws.com:amr": "authenticated"
}
}
}
]
}
動作確認
READMEに沿って、ハードコードされたAWSリソースの値を変更します。
diff --git a/src/app/service/aws.service.ts b/src/app/service/aws.service.ts
index 59b17cb..0cb86b6 100644
--- a/src/app/service/aws.service.ts
+++ b/src/app/service/aws.service.ts
@@ -117,7 +117,7 @@ export class DynamoDBService {
static getLogEntries(mapArray:Array<Stuff>) {
var params = {
- TableName: 'LoginTrail',
+ TableName: 'LoginTrailmycognitosample',
KeyConditionExpression: "userId = :userId",
ExpressionAttributeValues: {
":userId": AWS.config.credentials.params.IdentityId
@@ -147,7 +147,7 @@ export class DynamoDBService {
static write(data:string, date:string, type:string):void {
DynamoDBService.DDB = new AWS.DynamoDB({
- params: {TableName: 'LoginTrail'}
+ params: {TableName: 'LoginTrailmycognitosample'}
});
diff --git a/src/app/service/cognito.service.ts b/src/app/service/cognito.service.ts
index a720d23..b2ef4de 100644
--- a/src/app/service/cognito.service.ts
+++ b/src/app/service/cognito.service.ts
@@ -24,9 +24,9 @@ export class CognitoUtil {
public static _REGION = "us-east-1";
- public static _IDENTITY_POOL_ID = "us-east-1:fbe0340f-9ffc-4449-a935-bb6a6661fd53";
- public static _USER_POOL_ID = "us-east-1_PGSbCVZ7S";
- public static _CLIENT_ID = "hh5ibv67so0qukt55c5ulaltk";
+ public static _IDENTITY_POOL_ID = "us-east-1:aaaa-bbbb-ccccc-dddd";
+ public static _USER_POOL_ID = "us-east-1_AAAABBBBCCCC";
+ public static _CLIENT_ID = "aaaabbbbccccdddd11112222333";
public static _POOL_DATA = {
UserPoolId: CognitoUtil._USER_POOL_ID,
@@ -108,7 +108,7 @@ export class CognitoUtil {
export class UserRegistrationService {
constructor(@Inject(CognitoUtil) public cognitoConfigs:CognitoUtil) {
-
+ AWSCognito.config.update({accessKeyId: 'anything', secretAccessKey: 'anything'});
}
register(user:RegistrationUser, callback:CognitoCallback):void {
READMEの修正だけだと実行時にエラーが出てうまく動かなかったので、AWSCognito.config.update({accessKeyId: 'anything', secretAccessKey: 'anything'});
を加えています。
参考:User Pools for Amazon Cognito - CredentialsError: Missing credentials in config
また、ローカルで実行する前に、Cognito UserPoolsの設定を変更しておく必要があります。この設定変更によって、アカウント作成時の確認メールが送信されます。
そして実行します。
$ npm start
> aws-cognito-angular2-quickstart@1.0.0 start /Users/tannai.yuki/.ghq/github.com/awslabs/aws-cognito-angular2-quickstart
> ng server
Livereload server on http://localhost:49152
Serving on http://localhost:4200/
Build successful - 2422ms.
Slowest Trees | Total
----------------------------------------------+---------------------
BroccoliTypeScriptCompiler | 1528ms
vendor | 627ms
Slowest Trees (cumulative) | Total (avg)
----------------------------------------------+---------------------
BroccoliTypeScriptCompiler (1) | 1528ms
vendor (1) | 627ms
localhost:4200にアクセスして、アカウントを作成してみます。
アカウント作成直後のUserPoolsの画面が以下です。User StatusがUnauthenticatedになっています。
少し待つと登録メールアドレスに確認コードが送信されてくるので、それをブラウザから入力すると以下のように値が変化します。
改めてログインすると、DynamoDBに履歴が格納され、それをアプリから参照することができます。
この履歴はログイン・ログアウト時にDynamoDBに格納され、それを参照しています。
Federated IdentityのAuthentication Providerに、UserPoolが追加されていることがわかります。
まとめ
サンプルを利用して、Cognito UserPoolsが実際に動く様子を確認することができました。
Angular2のサンプルとしても良いコードだと思うので、みなさんもぜひ動かしてみてください。