LoginSignup
19
20

More than 5 years have passed since last update.

javascriptでCognitoユーザプール認証

Last updated at Posted at 2018-08-13

javascriptからCognitoのユーザプールで認証する方法を確認しました。
Amazon API GatewayのオーソライザーとしてCognito認証を指定することができますが、API Gatewayにアクセスする際にはCognito認証で取得したIDトークンが必要となります。
今回はIDトークンの取得とAPIへの与え方の確認になります。(qiita初投稿です)

0. 今回利用するサービスやモジュールたち

  1. Cognito (ユーザプール)
  2. node.js (javascript runtime)
  3. amazon-cognito-identity-js (Cognito javascript SDK)
  4. Axios (XHR library)

1. Cognito (ユーザプール) の設定

今回はユーザ・パスワードで認証させるだけなので、シンプルな構成でユーザプールを作成します。
ユーザプールIDとアプリクライアントIDはCognito認証時のパラメータとして必要となります。

  1. ユーザプールを作成していきます。
    userpool_1.png

  2. アプリクライアントの追加は実行しておきます。
    userpool_2.png

    userpool_3.png

  3. アプリクライアントの追加が完了したらユーザプールを作成します。
    userpool_4.png

完了したらCognito認証で利用するユーザも作成しておきましょう。
userpool_5.png

またユーザプールIDとアプリクライアントIDも確認しておきます。
(それぞれユーザプールの全般設定、アプリの統合>アプリクライアントの設定で確認します。)

2. Node.jsの設定

詳細は検索するなり参考サイトを確認ください。
MacOS(nodebrew)の場合は以下となります。

vi ~/.bash_profile
   export PATH=$HOME/.nodebrew/current/bin:$PATH #この行を追記

brew install nodebrew
nodebrew install v8.10.0
nodebrew use v8.10.0

node.jsはDocker公式イメージが配布されているので、Dockerコンテナを使う手もありと思います。

docker pull node
docker run -it --name node node /bin/bash
...Dockerコンテナ内でセットアップ...。

以下のjavascriptライブラリを使うのでnode実行環境にインストールしておきます。(global installの方が良い?その場合はnpm install -g)
npm install --save amazon-cognito-identity-js
npm install --save axios
npm install --save node-fetch
以下のjavascriptを実行する際に必要となります。

3. Cognito認証するスクリプト実装

ユーザプール情報や認証データ情報を格納したオブジェクトをもとにCognitoUserオブジェクトを作成。
authenticateUser関数を実行し認証に成功すると、コールバック(onSuccess)に指定した関数が呼ばれます。(認証処理に失敗するとonFailureがコールされます)
コールバック関数内でAPIコールを行う処理を実装していますが、もっと良い方法があるかもしれません。
初回ログイン時はパスワード変更が必要となりますので(newPasswordRequiredがコールバックされる)、暫定で同一パスワードを設定します。
またnode.jsからスクリプトを直接実行する場合、ライブラリ群はCommonJS Modulesの形式でインポート(require)する必要があるようです。(SPAフレームワークの場合はES Modules形式も良いもよう)

testauth.js
global.fetch = require('node-fetch')
const AmazonCognitoIdentity = require('amazon-cognito-identity-js');
const axios = require('axios');
const config = require('./config')

login = function () {
    let poolData = {
        UserPoolId: config.UserPoolId,
        ClientId: config.ClientId
    };
    let userData = {
        Username: config.Username,
        Pool: new AmazonCognitoIdentity.CognitoUserPool(poolData)
    };
    let cognitoUser = new AmazonCognitoIdentity.CognitoUser(userData);

    let authenticationData = {
        Username: config.Username,
        Password: config.Password
    };
    let authenticationDetails = new AmazonCognitoIdentity.AuthenticationDetails(authenticationData);

    cognitoUser.authenticateUser(authenticationDetails, {
        onSuccess: function (result) {
            let idToken = result.getIdToken().getJwtToken(); //Cognito認証で取得したIDトークン。 API gatewayへのアクセスに必要となる。
            get(idToken);  //IDトークンを指定してHTTPリクエスト(GET)を実行!
        },
        onFailure: function (err) {
            console.log(err);
        },
        newPasswordRequired: function (userAttributes, requiredAttributes) {
            cognitoUser.completeNewPasswordChallenge(config.Password, {}, this);
        }
    });
}

続いてHTTPアクセス用の関数の処理を追加します。
XHRライブラリはAxiosを使いました。
axios.get関数にて指定したURLへGetリクエストを送信できます。
Cognito認証を有効にしたAmazon API Gatewayにアクセスする場合、AuthorizationヘッダーにIDトークンを指定します。

testauth.js
get = function (idToken) {
    let headers = { headers: { 'Authorization': idToken } };

    axios.get(config.apiGatewayUrl, headers).then(
        function (res) {
            console.log(res.data);
        }
    ).catch(
        function (err) {
            console.log(err);
        }
    );
};

login(); //おっと、こいつがないとAPIコールされんかったです。

ユーザプール情報や認証情報は外部スクリプトに記載しておき、処理時にrequireでインポートします。

config.js
module.exports =  {
    apiGatewayUrl: 'https://xxxxx.xxxx.amazonaws.com/yourapi',
    UserPoolId: 'CognitoユーザプールID',
    ClientId: 'CognitoユーザプールのクライアントアプリID',
    Username: 'Cognito認証を利用するユーザのID',
    Password: 'Cognito認証を利用するユーザのパスワード'
}


上記を用意したら、コマンドラインからのスクリプト実行にてAPIコールが可能です。

node testauth.js

APIコールのレスポンスがコンソールに出力されますが、スクリプトやAPI側に必要に応じて何らかの処理を実装します。


まとめ

javascriptからCognitoのユーザプールで認証し、その際に取得したIDトークンをHTTPヘッダーに含めAPIコールを行う処理を試してみました。次はAmazon API Gatewayの実装方法を確認していきたいと思います。
また誤り漏れや改善点があれば適宜修正していきたいと思います。(例によって説明不足のところもあるので・・・。)


参考サイト

Amazon-Web-Servicesを使ったサーバーレスアプリケーション開発ガイド(書籍)
DockerHub(node)
nodebrew
fetch is not defined #403
amazon-cognito-identity-js
axios

19
20
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
20