
最近Lex絡みでちょいちょいAWS Amplifyをいじっていて、Amazon Cognitoちゃんといじったことないなーと思ったので、入門してみました。
ちなみに、題材はこの辺を参考にさせてもらいました、というか、ほぼほぼ「写経」なんですが、一部古い記載もあったので、まあ一応現時点での最新ということで。
目次
- 目次
- API GatewayでサンプルのAPIを作成
- Cognitoユーザープールの作成
- API GatewayにCognitoユーザープールで認証をかける
- Cognitoユーザープールへのユーザ追加
- 認証
- まとめ
API GatewayでサンプルのAPIを作成
まずは、API GatewayでサンプルとなるAPIを作成します。「APIを作成」をクリック。

APIタイプは「REST API」にします。「インポート」をクリック。

「プロトコルを選択する」は「REST」、「新しい API の作成」は「APIの例」を選択すると、サンプルで用意されている「PetStore」のAPIがインポートされますので、「インポート」をクリックします。

APIが作成されたら「アクション」→「APIのデプロイ」をクリック。

デプロイのステージを適当に設定します。今回は"initial"にしました。「デプロイ」をクリック。

"initial"ステージがデプロイされました。左のステージ名をクリックします。

APIのエンドポイントがツリー形式で表示されます。/pets/{petid}のところにあるGETをクリックして表示されるURLをコピーしてください。

curlコマンドでURLにアクセスしてみます。その際に末尾の{petid}のところは適当な数値を設定してみてください。
$ curl https://XXXXXXXXXXXX.execute-api.ap-northeast-1.amazonaws.com/initial/pets/1 { "id": 1, "type": "dog", "price": 249.99 } $ curl https://XXXXXXXXXXXX.execute-api.ap-northeast-1.amazonaws.com/initial/pets/2 { "id": 2, "type": "cat", "price": 124.99 }
APIが動作しているのがわかりますね。もちろん/petsのエンドポイントも動作します。
$ curl https://XXXXXXXXXXXX.execute-api.ap-northeast-1.amazonaws.com/initial/pets [ { "id": 1, "type": "dog", "price": 249.99 }, { "id": 2, "type": "cat", "price": 124.99 }, { "id": 3, "type": "fish", "price": 0.99 } ]
Cognitoユーザープールの作成
ではこのAPIにCognitoで認証をかけるために、ユーザープールを作成しましょう。Cognitoのページを開いて「ユーザープールの管理」をクリック。

「ユーザープールを作成する」をクリックします。2箇所ありますがどちらでもよいです。

ユーザープール名を設定します。今回はuser_pool_testにしました。入力したら「デフォルトを確認する」をクリックします。

いろいろ設定が表示されますが、デフォルトのまま「プールの作成」をクリックします。

「ユーザープールは正常に作成されました」と表示されればOKです。上の方に表示されている「プールID」を後で使いますので、メモしておきましょう。

次にアプリクライアントを作成します。左のメニューから「アプリクライアント」をクリック。

「アプリクライアントを追加」をクリックします。

アプリクライアント名は適当に設定します。今回はcognito-cliとしました。「認証用の管理APIのユーザ名パスワード認証を有効にする(ALLOW_ADMIN_USER_PASSWORD_AUTH)」にチェックを入れ、以下のチェックは外します。
- クライアントシークレットを作成
- Lambdaトリガーベースのカスタム認証を有効にする (ALLOW_CUSTOM_AUTH)
- SRP (セキュアリモートパスワード) プロトコルベースの認証を有効にする (ALLOW_USER_SRP_AUTH)
そして「アプリクライアントの作成」をクリックします。

アプリクライアントIDが発行されますので、こちらもメモしておいてください。

API GatewayにCognitoユーザープールで認証をかける
ではAPI Gatewayに戻りましょう。左のメニューから「オーサライザー」をクリックします。

「新しいオーサライザーの作成」をクリックします。

名前は適当につけてください。今回はuser-pool-authにしました。タイプは「Cognito」を選択し、Cognitoユーザープールで先ほど作成したユーザープール名を選択します。「トークンのソース」はAuthorizationを入力します。最後に「作成」をクリックします。

オーサライザーが作成されました。ではAPIリクエスト時にこのオーサライザーを使うように設定します。「リソース」をクリックします。

/petsのGETをクリックして、「メソッドリクエスト」をクリックします。

設定の「認可」のところにある鉛筆アイコンをクリックします。

先ほど作成したオーサライザー名が表示されますので、これを選択します。

選択したら、小さいチェックマークが表示されるのでクリックします。これで確定です。

これで認証の設定ができましたので、デプロイしましょう。「アクション」から「APIのデプロイ」をクリックします。

ステージを適当に設定します。今回はauthにしました。「デプロイ」をクリックします。

新しいステージでAPIのエンドポイントURLが発行されます。

curlでアクセスしてみましょう。/petsにアクセスしてみます。
$ curl https://XXXXXXXXXXXX.execute-api.ap-northeast-1.amazonaws.com/auth/pets {"message":"Unauthorized"}
Unauthorizedと表示されてアクセスできませんでした。つまりCognitoの認証が必要になるということですね。認証を行って発行したトークンをAuthorizationヘッダで指定すればアクセス可能になります。
ちなみに/pets/{petid}の方は設定していないのでアクセスできます。エンドポイントごとに設定しないといけないのですね。
$ curl https://XXXXXXXXXXXX.execute-api.ap-northeast-1.amazonaws.com/auth/pets/1 { "id": 1, "type": "dog", "price": 249.99 }
Cognitoユーザープールへのユーザ追加
ではCognitoにユーザを作成しましょう。Cognitoの管理画面から追加すればいいのではないかなと思ったのですが、ちょっとうまく行かなかったのでaws-cliでやります。
まず、ユーザのサインアップ。メールアドレス等、適宜置き換えて実行してください。少し補足。
- 指定したメールアドレスにメールアドレス検証用のメールが飛びますので、存在するメールアドレスを使用してください。
- パスワードはデフォルトでルールが設定されています。アルファベット大文字・小文字、数字、記号の組み合わせで8文字以上みたいですね。
$ aws cognito-idp sign-up \ --client-id アプリクライアントID \ --username メールアドレス \ --password パスワード \ --user-attribute "Name=email,Value=メールアドレス" { "UserConfirmed": false, "CodeDeliveryDetails": { "Destination": "****@****.***", "DeliveryMedium": "EMAIL", "AttributeName": "email" }, "UserSub": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" }
これでユーザが作成されます。Cognitoのユーザープールにも表示されていますね。

ただし、上記にもある通り、アカウントはUNCONFIRMED(未検証)となっていますので、検証を行う必要があります。上記メールアドレスのメールボックスを確認すると以下のようなメールが届いているかと思います。

この検証コードを使用して、ユーザアカウントの検証を行います。
$ aws cognito-idp confirm-sign-up \ --client-id アプリクライアントID \ --username メールアドレス \ --confirmation-code 検証コード
ユーザープール上でもCONFIRMEDになれば、認証に利用できるようになります。

認証
ではCognitoで認証してサインインしてみます
$ aws cognito-idp admin-initiate-auth \ --user-pool-id ユーザープールID \ --client-id アプリクライアントID \ --auth-flow ADMIN_USER_PASSWORD_AUTH \ --auth-parameters "USERNAME=メールアドレス,PASSWORD=パスワード" { "ChallengeParameters": {}, "AuthenticationResult": { "AccessToken": "XXX...XXX", "ExpiresIn": 3600, "TokenType": "Bearer", "RefreshToken": "XXX...XXX", "IdToken": "XXX...XXX" } }
サインインが成功すると、トークンが3つ返ってきます。API Gatewayの認証に必要なのはIdTokenですので、これを環境変数にセットします。
$ ID_TOKEN=$(aws cognito-idp admin-initiate-auth --user-pool-id ユーザープールID --client-id アプリクライアントID --auth-flow ADMIN_USER_PASSWORD_AUTH --auth-parameters "USERNAME=メールアドレス,PASSWORD=パスワード" | jq -r .AuthenticationResult.IdToken)
このIDトークンをAurhorizationヘッダに指定して、再度curlでAPIにアクセスしてみましょう。
$ curl https://XXXXXXXX.execute-api.ap-northeast-1.amaonaws.com/auth/pets {"message":"Unauthorized"} $ curl -H "Authorization:$ID_TOKEN" https://XXXXXXXX.execute-api.ap-northeast-1.amaonaws.com/auth/pets [ { "id": 1, "type": "dog", "price": 249.99 }, { "id": 2, "type": "cat", "price": 124.99 }, { "id": 3, "type": "fish", "price": 0.99 } ]
はい、アクセスできましたね!
まとめ
とりあえずユーザープールはこんな感じ。IDプールも試してみたいのだけど、どうするのがよいかなぁ・・・