【AWS】Amplifyを使わずに最小構成でCognitoログイン及びクライアント認証を実装する
Amplifyを使わずにCognitoログイン及びクライアント認証を実装する方法です。
この記事ではJavaScriptを例に紹介しますが、SDKを使わずにAPIを直接叩くため、言語によらず実装可能です。
Cognitoの設定
ユーザープールの管理
ユーザープールとは
ユーザープールとは、ユーザーのサインアップやサインインを提供するユーザディレクトリです。
Cognitoでユーザー管理をするために必要なもの、という認識で大丈夫です。
より詳しく知りたい方は、以下公式ドキュメントをご覧ください。
ユーザープールの作成
まずはユーザープールを作成します。
AWSマネージメントコンソールにサインインし、サービスからCognitoを検索して開き、「ユーザープールの管理」をクリックします。
次に、右上に表示されている「ユーザープールを作成する」をクリックします。
任意のプール名を入力し、「デフォルトを確認する」をクリックします。
ここで入力するプール名はアカウントを管理したいサービス名など、わかりやすい名前をつけておくと良いと思います。
パスワード強度の変更
サイドメニューの「ポリシー」からパスワードの強度を変更します。
今回はテスト用なので、全てのチェックを外して「変更の保存」をクリックします。
アプリクライアントの追加
次に、サイドメニューの「アプリクライアント」から、「アプリクライアントの追加」をクリックします。
任意のアプリクライアント名を入力し、「クライアントシークレットを生成」のチェックを外します。
その後、「アプリクライアントの作成」をクリックします。
プールの作成
最後に、サイドメニューの「確認」をクリックし、入力内容を確認して「プールの作成」をクリックします。
アプリクライアントの設定
プールの作成が完了したら、後ほど利用するアプリクライアントIDをメモに控えておきます。
サイドメニューの「アプリクライアントの設定」をクリックし、IDをコピーしてメモに控えておきます。
有効なIDプロバイダの「Cognito User Pool」にチェックを入れ、Cognitoの認証を利用するようにします。
「サインインとサインアウトのURL」の「コールバックURL」にログイン後にリダイレクトしたいURLを指定します。
今回はローカルサーバでテストするため、http://localhost:8080/
を指定します。
次に、cognitoのログイン画面でログイン後に返される情報を設定します。
「OAuth2.0」の「許可されているOAuthフロー」の「Authorization code grant」にチェックを入れます。
ここにチェックを入れると、ログイン後に認可コードを取得可能になります。
続いて、「許可されているOAuthスコープ」では「openid」にチェックを入れて、「変更の保存」をクリックします。
ドメイン名
続いて、Cognitoのドメイン名を設定します。
今回利用するAPIエンドポイントや、ログイン画面のドメインになります。
任意のドメイン名を入力し、「使用可能かチェク」をクリックして使用可能なことを確認して、「変更の保存」をクリックします。
これでユーザープールの作成が完了しました。
ユーザーを作成
次に、ログインに必要なユーザを作成します。
サイドメニューの「ユーザとグループ」をクリックし、「ユーザの作成」をクリックします。
ユーザ名と仮パスワード、Eメールを入力し、その他チェックは外します。
入力が完了したら、「ユーザーの作成」をクリックします。
これでログインに必要なユーザが作成できました。
ログインして認可コードを取得
次に、Cognitoが用意しているログイン画面を利用して先程作成したユーザでログインし、リダイレクトされることを確認します。
また、リダイレクトされた際に、URLに認可コードが付与されていることも確認します。
ログイン
「アプリクライアントの設定」から、「ホストされたUIを起動」をクリックします。
先程作成したユーザ名と仮パスワードを入力して、「Sign in」をクリックします。
すると、パスワードの設定をするように促されるので、入力し「Send」をクリックします。
リダイレクトURLに認可コードが付与されていることを確認
予め作成したローカル環境のページに遷移され、リダイレクトURLにcode=xxx
という認可コードが付与されていることが確認できます。
この認可コードを使って、クライアントからユーザ認証を行います。
クライアント認証
ログインができたので、次に認可コードを使ってユーザのクレデンシャルを取得します。
クライアントでユーザ認証されているかどうかを判定する場合は、この認証を利用します。
また、ユーザ情報を取得する場合は、ここで取得するクレデンシャルを用いて取得します。
認可コードを用いてクレデンシャルを取得
Cognitoのログイン画面からログイン後、リダイレクトURLに付与された認可コードを用いて、以下エンドポイントにアクセスしてクレデンシャルを取得します。
curlでリクエストする
まずは、認可コードを用いてクレデンシャルを取得できることを確認するため、curlコマンドを用いて確認します。
$ curl -X POST \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=authorization_code" \
-d "client_id={クライアントID}" \
-d "scope=openid" \
-d "redirect_uri=http://localhost:8080/" \
-d "code={認可コード}" \
"https://test0987.auth.ap-northeast-1.amazoncognito.com/oauth2/token"
{
"id_token":"xxxxxx", # ユーザ情報がJWT形式で格納されているトークン
"access_token":"xxxxx", # ユーザ情報などを取得する際に利用するトークン
"refresh_token":"xxxxx", # 再認証するためのトークン
"expires_in":3600, # トークンの有効期限(単位:秒)
"token_type":"Bearer" # トークンタイプ
}
クレデンシャルが取得できました。
IDトークンはJWT形式でユーザ情報が入っています。
https://jwt.io/ にIDトークンを貼り付けてデコードすると、次のようにユーザ情報が確認できます。
JavaScriptでリクエストする
curlでリクエストが成功したので、続いてJavaScriptで認可コードを用いてクレデンシャルを取得するコードを実装します。
Cognitoログイン画面からリダイレクト後、以下コードを実行します。
※クライアントIDなどは適宜置き換えてください。
async function postData(url, data) {
const response = await fetch(url, {
method: 'POST',
cache: 'no-cache',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: data,
});
return response.json();
}
// URLから認可コード取得
const query = location.search.replace('?', '');
const authCode = query.split('=')[1];
const clientId = 'クライアントID';
const endpoint = 'https://test0987.auth.ap-northeast-1.amazoncognito.com/oauth2/token';
// application/x-www-form-urlencoded形式でbodyを作成
const requestBody = `grant_type=authorization_code&client_id=${clientId}&scope=openid&redirect_uri=http://localhost:8080/&code=${authCode}`;
postData(endpoint, requestBody).then((data) => {
console.log(data);
});
無事にクレデンシャルが取得できました。
以上が、Amplifyを使わずに最小構成でCognitoログイン及びクライアント認証を実装する方法でした。
Discussion