AmplifyでCognitoのHosted UIを利用した認証を最低限の実装で動かしてみて動作を理解する
2024/12/16 追記
このブログで利用しているAmplify.jsのバージョンが古く、現状のAmplify.jsでは再現できません。
最新版はこちらのブログをご参照ください。
AmplifyでCognitoのマネージドログインを利用した認証を最低限のReact実装で動かしてみて動作を理解する | DevelopersIO
Amplifyを使うと、Cognitoを利用して簡単に認証機能を作れて便利です。
詳しくは弊社ブログをご覧ください。
- AWS Amplify+Angular6+Cognitoでログインページを作ってみる ~バックエンド編~ | Developers.IO
- AWS AmplifyとAngular8を使ってCognitoでAWS Management Consoleにログインするページを作ってみる | Developers.IO
また、こういったログインのほかに、CognitoにはホストされたUIを利用してユーザー認証をするという機能があります。 イメージ動画を作成したのでこちらを御覧ください。
この方法を採用すると何がうれしいかというと、外部IDプロバイダ(例えば、Facebookでログインするとか、Googleでログインするといったやつ)を追加したときに、こんな形でログインUIをCognitoが自動で追加してくれます。
ただし、ログインUI用の別URLにジャンプする動作をするという関係上、Cognitoのユーザーだけを利用する場合とは異なり、認証フローが大きく変わります。
その認証フローが大きく変わるという部分を Amplifyがうまいことやってくれて 、 プログラム開発者はほとんど意識することなく認証機能を実装できます。スゴイですね!
Amplifyの公式ドキュメントに、ReactでCognitoを利用してFacebookログインやGoogleログインを実装するサンプルがあります。 詳しくはこちらを御覧ください。
動くものを作りたいだけであれば、ここまで読んでいただければ大丈夫です。
ありがとうございました。
ここから先は、「うまいことってなんなんだよ。全然納得できない。具体的に何をどうしてるんだよ。」 みたいなことを考えてしまう私みたいなひねくれ者のために、 知らなくても困らないけど、知っているともっと楽しめるかもしれない、 AmplifyとCognitoでホストされたUIがどんな認証フローをとっているのか? そして、具体的に何をうまいことやってくれているのか?という話をします。
構成概要図
サンプルとしてAmplifyとCognitoユーザープールを使ってざっくりこんな感じの環境を作ります。
今回、必要最低限の実装ということで、画面は1つで、ReactやVueのようなSPAフレームワークは使いません。
認証フローの話をする前に、いったん環境を構築してみましょう。
動くものがあったほうが理解しやすいと思います。
サンプルプログラム置き場
今回作成したプログラムはGitHubで公開しています。 実際に動かしてみたい方はこちらから git clone
してください。
前提条件
サンプルプログラムを動かす場合、次のコマンドが利用できるようにインストールをしておいてください。
$ node --version v12.16.2 $ npm --version 6.14.5 $ aws --version aws-cli/2.0.10 Python/3.7.4 Darwin/19.5.0 botocore/2.0.0dev14
Cognito環境の構築
まずは git clone
して環境一式をGitHubから取ってきます。
$ git clone https://github.com/rednes/cognito-simple-example-for-external-idp.git $ cd cognito-simple-example-for-external-idp
次にCloudFormationを利用して、Cognitoの環境を作ります。 次のコマンドを実行すると、Cognitoの環境が作れます。
コマンドが具体的に何をしているか気になる方は、 package.json で定義していますので、詳細はそちらを御覧ください。
$ export AWS_DEFAULT_PROFILE=<<YOUR_AWS_PROFILE>> $ npm run cfn-deploy
しばらくすると、CloudFormationでCognitoの環境構築が完了します。 次のコマンドで出力結果を確認してください。 次のような形で結果が返ってくれば大丈夫です。
$ npm run cfn-describe --------------------------------------------------------- | DescribeStacks | +------------------------+------------------------------+ | CognitoRegion | ap-northeast-1 | | CognitoUserPool | ap-northeast-1_XXXXXXXXX | | CognitoUserPoolClient | XXXXXXXXXXXXXXXXXXXXXXXXXXX | +------------------------+------------------------------+
次に、ひとつだけマネジメントコンソールで設定してほしい作業があります。
Cognitoがホストしているログイン用のURLは、Cognitoが用意する画面です。 そのため、アプリケーションとはまったく別ドメインのサイトになります。
このサブドメインの名前を決めて、Cognitoで設定する必要があります。 サブドメインの設定手順を示します。
Cognitoユーザープールのマネジメントコンソール画面を開き、 CognitoSimpleExampleUsers という名前のユーザープールができているので開きます。
左側のメニューのドメイン名を選択して、ドメインのプレフィックス を入力してください。 ドメインのプレフィックスは後で利用するのでメモしておいてください。
以上でCognitoの環境構築は終了です。
アプリケーションの設定
アプリケーションの設定ファイルを、Cognitoの環境とあわせた値に変更します。
/public/js/amplifyConfig.js.example
ファイルを /public/js/amplifyConfig.js
にコピーして、さきほどメモしたドメインのプレフィックスを CognitoDomainPrefix
に入力してください。
CognitoUserPool等の値は、さきほど実行した npm run cfn-describe
コマンドで確認できるのでこれも入力してください。
$ npm run cfn-describe --------------------------------------------------------- | DescribeStacks | +------------------------+------------------------------+ | CognitoRegion | ap-northeast-1 | | CognitoUserPool | ap-northeast-1_XXXXXXXXX | | CognitoUserPoolClient | XXXXXXXXXXXXXXXXXXXXXXXXXXX | +------------------------+------------------------------+
let CognitoRegion = 'ap-northeast-1'; let CognitoUserPool = 'ap-northeast-1_XXXXXXXX'; let CognitoUserPoolClient = 'dummy'; let CognitoDomainPrefix = 'dummy'; let amplifyConfig = { Auth: { region: CognitoRegion, userPoolId: CognitoUserPool, userPoolWebClientId : CognitoUserPoolClient, oauth: { domain: `${CognitoDomainPrefix}.auth.${CognitoRegion}.amazoncognito.com`, scope: ['openid'], redirectSignIn: 'http://localhost:3000', redirectSignOut: 'http://localhost:3000', responseType: 'code' } } };
次に、ローカルでexpressサーバーを動かすために、次のコマンドを実行してnodeパッケージをインストールしてください。
$ npm install --production
次のコマンドを実行して、待機状態になれば成功です。 http://localhost:3000
でアクセスできるローカルサーバーができました。
$ npm start Node.js is listening to PORT:3000
ホストされたUIを利用したログインの流れを確認してみる
ブラウザから http://localhost:3000
にアクセスすると、こんな感じのSign Inボタンがあるだけの画面が表示されます。
ここでSing Inボタンを押すと、Cognitoのログイン画面に飛びます。
ユーザー登録の説明を省いて、すでにユーザーは登録済みという前提で進めます。
E-mail/Passwordを入力してサインインします。
そうすると、元のページに戻ってユーザー認証が完了し、Cognitoの発行したトークンがベロっと画面に表示されるというアプリケーションです。
Sign Outボタンを押すと、サインアウトされてトークンの表示もなくなります。
ただこれだけのシンプルアプリケーションです。
それではコードを読んでいきましょう。 60行程度なので、すぐ読めると思います。
コードの解説
server.js
まず、 server.js
で動かしているexpressです。 これ自体はほとんど何もしていません。
これは public/js
フォルダに入っている、 aws-amplify.min.js
等のローカルにあるJavaScriptファイルをHTMLから読み込みたいという理由だけで動作させています。
server.js
がやっているのは、トップページにアクセスがあったとき、 views/index.ejs
を何も手を加えずに配信しているだけです。
そのため、メインのロジックは views/index.ejs
のscriptタグに書いています。
views/index.ejs
views/index.ejs
もやっていることはシンプルです。
10行目の onload
で、画面の読み込みが終わったら24行目からの onLoad
ファンクションを実行しています。
そして ./js/aws-amplify.min.js
からAmplifyとAuthクラスを取り出して、28行目の Amplify.configure
でamplifyの設定をしています。
30行目ではaddEventListnerを使って、Sign Inボタンが押されたら Auth.federatedSignIn
を実行するように設定しています。 このファンクションが、CognitoのホストされたUIへリダイレクトしている処理 の正体です。
そして38行目で Auth.currentSession
を使って、ログインしているユーザーの情報を取得しています。
取得できたら document.getElementById('sessionInfo').innerText
にベロっと吐き出しています。
取得できなかったら(ユーザーがログインしていなかったら)、コンソールにerrorだけ吐き出して何もしません。
こんな感じのJavaScriptです。
ここで何が言いたいかというと、プログラムを書く際に 明示的に書いている認証処理 は48行目の Auth.federatedSignIn
だけということです。
これ以外ほぼ何もせずに認証処理が実装できています。スゴイですね!
プログラムが具体的にイメージできたところで、そろそろCognitoの認証フローの話に入っていきます。
Cognitoの認証フロー
CognitoのOAuthフローとして、次の 3つのフロー を利用することが許可されています。
- Authorization code grant
- Implicit grant
- Client credentials
Authorization code grantはPKCEを併用できます。
ですので、4種類あると言ってもよいかもしれません。
- Authorization code grant
- PKCE未使用
- PKCE併用
- Implicit grant
- Client credentials
参考: サインアップおよびサインインに Amazon Cognito のホストされた UI を使用する - Amazon Cognito
本筋から外れるので、本ブログでは 各フローについての詳細までは立ち入りません 。
どういう場合にどのフローを選択するかだけざっと説明します。
- Authorization code grant(基本的にこのフローが推奨)
- PKCE未使用(Webアプリケーション等、トークンをサーバが仲介して取得する場合。通常クライアントシークレットを設定する。)
- PKCE併用(SPAやモバイルアプリ等、トークンをユーザーが直接取得する場合)
- Implicit grant(Authorization code grantが不可能な場合選択。PKCE併用したcode grantが推奨される)
- Client credentials(エンドユーザーが認証に使うフローではない)
各フローはOAuth 2.0で定義されている認可フローとほぼ同じものですので、各フローの詳細はOAuth2.0認可フローをご参照ください。参考資料をブログの最後に貼っておきます。
今回のサンプルアプリケーションは、 トークンをユーザーがJavaScriptを使って直接取得 しておりSPAに相当します。
よって、推奨されている PKCEを併用するAuthorization code grant 決め打ちで説明します。
それでは、 PKCEを併用するAuthorization code grant フローとは何なのでしょうか?
PKCEを使用しないAuthorization code grant
いきなりPKCEを併用するAuthorization code grantの話をすると混乱するので、 いったんPKCEを使用しない場合のフローについて説明します。
本ブログでは、OAuth2.0の認可フローである一般的なAuthorization code grantの話というよりは、 CognitoのAuthorization code grantフローがどういう動きをしているのかという具体的な動きを説明します。
まずは、Authorization code grantフローの全体像をシーケンス図で示します。
Authorization code grant フローは、次のステップで進んでいきます。
ユーザーがアプリケーションに対してログイン要求を出すと、 アプリケーションはCognitoの 認可エンドポイント に対して認証リクエストを投げるための、リダイレクトレスポンスをユーザーに返します。(フロー図の01〜02)
そうすると、ユーザーは認可エンドポイントにリダイレクトされ、Cognitoに認証リクエストを投げることになります。 Cognitoはそれに応じてリダイレクトレスポンスで ログインエンドポイント(ログイン画面のURL) を返します。(フロー図の03〜04)
リダイレクトレスポンスが返ってくるので、ユーザーはログイン画面にリダイレクトされます。 ログイン画面が表示されるので、ユーザーはID/Passwordを入力してユーザーによる認証を行います。(フロー図の05〜07)
そうすると、Cognitoは 認可コード を発行して、リダイレクトレスポンスのURLクエリパラメーターに認可コードを添えてユーザーに返します。(フロー図の08)
リダイレクトレスポンスが返ってくるので、ユーザーは認可コードつきでアプリケーションのCallback URLへリダイレクトされます。(フロー図の09)
Callback URLのアクセスで認可コードを受け取ったアプリケーションは、その認可コードを使ってCognitoの トークンエンドポイント に対してトークンリクエストを投げます。(フロー図の11)
Cognitoはその認可コードが有効であると判断すれば、IDトークン,アクセストークン,リフレッシュトークン をアプリケーションに返します。(フロー図の12)
アプリケーションはIDトークンの検証をして問題なければ、ログイン完了したことをユーザーに伝えます。(フロー図の13〜14)
これが、 Authorization code grant フローの流れです。
これを読んで、Authorization code grant のイメージ、湧きましたでしょうか?
私はこの説明を文章で読んだけでは、さっぱりわかりませんでした。
具体的にCognitoに対して出しているリクエストを自分の手で実行してみると理解が進むと思います。
ですので、実際にシェルとブラウザで Authorization code grant フローを体験してみましょう。
シェルとブラウザでAuthorization code grantをやってみる
Authorization code grant フローのシーケンス図を再掲します。
まずは、認証リクエストをCognitoの認可エンドポイントに送り、リダイレクトレスポンスを受け取るところをやってみます。(フロー図の03〜04)
Cognitoの認可エンドポイントについての詳細は、こちらのドキュメントをご参照ください。
リクエストの送信先とするCognitoは、先ほどのサンプルアプリケーション用に構築したものを利用します。
そして、ドメイン名はログイン画面のURLのドメイン名と同じです。
つまり、ドメインプレフィックスを、 cognito-domain-prefix
として、リージョンを ap-northeast-1
で構築していた場合、認可エンドポイントのURLは、 https://cognito-domain-prefix.auth.ap-northeast-1.amazoncognito.com/oauth2/authorize
になります。
よって、次のように curl
コマンドを実行することで、この認可エンドポイントに対して認証リクエストを投げることができます。
$ CognitoRegion=ap-northeast-1 $ CognitoUserPoolClient=<<YOUR_COGNITO_CLIENT_ID>> $ CognitoDomainPrefix=<<YOUR_COGNITO_DOMAIN_PREFIX>> $ CognitoDomain=$(echo ${CognitoDomainPrefix}.auth.${CognitoRegion}.amazoncognito.com) $ curl -i "https://${CognitoDomain}/oauth2/authorize?response_type=code&client_id=${CognitoUserPoolClient}&redirect_uri=http://localhost:3000&state=xyz&scope=openid"
クエリパラメーターの項目と設定値について説明します。
- response_type
- code または token を指定します。認可コードを要求するAuthorization code grantの場合、 code を指定します。よって、今回は code を指定します。
- client_id
- CognitoユーザープールのクライアントIDを指定します。
- redirect_uri
- 認可コードを返すリダイレクト先のURLを指定します。今回は、http://localhost:3000 を指定します。
- state
- Cognitoがクライアントにリダイレクトして戻るときに、この値を含めるようになります。オプション値だが、CSRF攻撃を防ぐために設定することが強く推奨されています。
- scope
- スコープを指定します。OIDC認証をする場合、openid の指定が必須です。今回は opeind を指定します。
実際にこのリクエストを投げてみましょう。
そうすると、 302リダイレクト のレスポンスが返ってきて、 Locationレスポンスヘッダー にリダイレクト先のURLが示されていることがわかります。
HTTP/2 302 location: https://<<YOUR_COGNITO_DOMAIN_PREFIX>>.auth.ap-northeast-1.amazoncognito.com/login?response_type=code&client_id=<<YOUR_COGNITO_CLIENT_ID>>&redirect_uri=http%3A%2F%2Flocalhost%3A3000&state=xyz&scope=openid
また、LocationのURLから、リダイレクト先はログインエンドポイントであることがわかります。
このログインエンドポイントというのが、いわゆるCognitoがホストしているログイン画面のURLのことです。
次にこのリダイレクト先のURLへブラウザを使ってアクセスしてみます。(フロー図の05〜08)
そうするとこのようにCognitoのログイン画面が表示されます。 ログインするとlocalhostへリダイレクトされてくるので、ローカルサーバーがリクエストを受け取らないようにexpressサーバは終了しておいてください。
E-mail/Passwordを入力してログインすると、Cognitoからリダイレクトレスポンスが返ってきます。
リダイレクトレスポンスは次のような形をしています。
http://localhost:3000/?code=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX&state=xyz
state
には認証リクエストで指定したxyzが入っています。 通常CSRF攻撃を防ぐため、認証リクエストで送信した state
をアプリケーション側で保持しておき、リダイレクトで返ってきたstate
と一致しているかをアプリケーション側でチェックします。code
の値に入っているものが 認可コード です。 認可コード はトークンリクエストの際に必要です。
次に IDトークン ・ アクセストークン の取得処理です。 トークンエンドポイントに対してトークンリクエストをやってみます。(フロー図の11〜12)
Callbackで受け取った 認可コード を AuthorizationCode
環境変数に格納すると、次のように curl
コマンドを実行することで、トークンエンドポイントに対してトークンリクエストを投げることができます。
$ AuthorizationCode=<<YOUR_AUTORIZATION_CODE>> $ CognitoRegion=ap-northeast-1 $ CognitoUserPoolClient=<<YOUR_COGNITO_CLIENT_ID>> $ CognitoDomainPrefix=<<YOUR_COGNITO_DOMAIN_PREFIX>> $ CognitoDomain=$(echo ${CognitoDomainPrefix}.auth.${CognitoRegion}.amazoncognito.com) $ curl -X POST \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "grant_type=authorization_code" \ -d "client_id=${CognitoUserPoolClient}" \ -d "scope=openid" \ -d "redirect_uri=http://localhost:3000" \ -d "code=${AuthorizationCode}" \ "https://${CognitoDomain}/oauth2/token"
パラメーターの項目と設定値について説明します。
- grant_type
- authorization_code, refresh_token または client_credentials を指定します。今回はAuthorization code grantに沿ってトークンを要求しているので、authorization_code を指定します。
- client_id
- CognitoユーザープールのクライアントIDを指定します。
- scope
- スコープを指定します。OIDC認証をする場合、openid の指定が必須です。今回は opeind を指定します。
- redirect_uri
- 認可コードを要求したときに指定した redirect_uri と同じ値を設定する必要があります。今回は、http://localhost:3000 を指定します。
- code
- 認可コードを指定します。
トークンリクエストが成功すると、トークンレスポンスが次のような形で返ってきます。
{ "id_token": "eyJraWQ...5peOLw", "access_token": "eyJ...NISbew", "refresh_token": "ey...Kz7AnA", "expires_in": 3600, "token_type": "Bearer" }
この、 id_token
の値が IDトークン で、 access_token
の値が アクセストークン です。
これで、Cognitoからトークンが取得できてユーザーのログインが完了しました。
最後に、この IDトークン の中身を見てましょう。 IDトークン は JWT形式 でユーザーに関する情報が入っています。
そのため、jwt.io等のサイトやライブラリを使って中身を確認できます。
jwt.ioにIDトークンをコピー&ペーストしてみると、このように中に入っているユーザー情報を確認できます。
PKCEを併用するAuthorization code grant
ここまでPKCEを使用しないAuthorization code grantの話をしてきました。
PKCEを併用する場合もフロー自体は変わりません。 認可コードの横取り攻撃の対策のために、随所でパラメーターのやりとりが追加されます。
OAuth2.0のPKCEを理解するには、ゲストブロガーとしてAuth0社の筒井さんに書いていただいたこのブログがわかりやすいです。
PKCEの一般的な話はこちらのブログに説明をゆずり、本ブログではCognitoの具体的な動きを見ていきます。
PKCEを併用するAuthorization code grantフローの全体像をシーケンス図で示します。
PKCEを使用しないAuthorization code grant フローから追加された、赤字で書いた処理だけを説明します。
まず認証リクエストを送る前に、アプリケーション側で code_verifier
の発行と保存をし、code_verifier
を code_challenge_method
に沿った方法で code_challenge
に変換します。(フロー図の02)
ちなみに、Cognitoが対応しているcode_challenge_method
は現段階では S256 のみです。
その後、パラメーターに code_challenge
と code_challenge_method
を追加して認可エンドポイントに認証リクエストを投げるための、リダイレクトレスポンスをユーザーに返します。(フロー図の03)
そうすると、ユーザーは認可エンドポイントにリダイレクトされ、code_challenge
と code_challenge_method
パラメーターとあわせて、Cognitoに認証リクエストを投げることになります。 Cognitoはそれに応じてリダイレクトレスポンスで ログインエンドポイント(ログイン画面のURL) を返します。(フロー図の04〜05)
その後は、トークンリクエストする直前まで飛んで、Callback URL経由で認可コードを受け取った後、保存していた code_verifier
の読込と破棄をします。(フロー図の12)
その後、パラメーターに code_verifier
を追加してトークンエンドポイントにトークンリクエストを投げます。(フロー図の13)
これが、 PKCEを併用したAuthorization code grant フローです。
PKCEを併用したAuthorization code grantフローでの認証を採用する場合、アプリケーション側はこのフローに沿ってCognitoとパラメーターをやりとりする実装が必要です。
Amplifyも当然、このフローに沿って認証処理をしています。
Cognitoの認証フローが理解できたところで、いよいよAmplifyがうまいことやってくれていることを暴いていきます。
Amplifyがうまいことやってくれていること
Amplifyの設定
まず、Amplifyがうまいことやるための設定についてです。Amplify.configure
の引数としているこの値が重要です。
この設定で、AmplifyとCognitoがどの認証フローでやりとりするのか、どのCognitoのエンドポインと通信したいのか、リダイレクト時のコールバックURLが何なのかを定義しています。
let amplifyConfig = { Auth: { region: CognitoRegion, userPoolId: CognitoUserPool, userPoolWebClientId : CognitoUserPoolClient, oauth: { domain: `${CognitoDomainPrefix}.auth.${Region}.amazoncognito.com`, scope: ['openid'], redirectSignIn: 'http://localhost:3000', redirectSignOut: 'http://localhost:3000', responseType: 'code' } } };
参考: Authentication - Social sign-in (OAuth) - Amplify Docs
特に重要なパラメーターの項目と設定値について説明します。
- Auth.userPoolWebClientId
- CognitoユーザープールのクライアントIDを指定します。認証リクエストやトークンリクエストする際に、クライアントIDとして利用されます。
- Auth.oauth.domin
- 認可エンドポイント等、各エンドポイントにアクセスする際のCognitoのエンドポイントのドメイン名として利用されます。
- Auth.oauth.scope
- スコープを指定します。OIDC認証をする場合、 openid の指定が必須です。今回は opeind を指定しています。
- Auth.oauth.redirectSignIn
- 認証リクエストやトークンリクエストをする際のリダイレクト先URLを指定します。今回は、 http://localhost:3000 を指定しています。
- Auth.oauth.responseType
- code または token を指定します。Authorzation code grantフローを採用する場合、code を指定します。Implicit grantフローを採用する場合、 token を指定します。今回は、Authorzation code grantフローを採用したいので、 code を指定します。
ちなみに、 Auth.oauth.redirectSignIn
はCognitoのこの画面で設定する コールバックURL と一致していないと、Cognito側が受け付けてくれません。
また、Auth.oauth.responseType
で code
を指定する場合は、 Authorzation code grant フローを採用することになります。その場合、Cognitoのこの画面で Authorization code grant を指定する必要があります。token
を指定する場合は、 Implicit grant フローを採用することにります。その場合、 Implicit grant を指定する必要があります。
また、 Auth.oauth.scope
で指定できるスコープは、Cognitoのこの画面で 許可されているOAuthスコープ に限ります。
参考: ユーザープールのアプリクライアントの設定 - Amazon Cognito
Amplifyの動作
PKCEを併用するAuthorization code grant フローのシーケンス図を再掲します。
Amplifyが何をうまいことやっているのか明らかにするために、 先ほど構築したサンプルアプリケーションとブラウザの開発者ツールを使ってAmplifyの動きを追ってみます。
Auth.federatedSignIn
にブレークポイントをしかけた上で、Sign Inボタンをおして Auth.federatedSignIn
を実行し、ステップインで処理を追っていきます。
そうすると、セッションストレージに state
と code_verifier
を保存している動きが見えます。(フロー図の02)
その後、ブレークから復帰してCognitoのログイン画面まで遷移すると、Cognitoの認可エンドポイントに対して、state
, code_challenge
, code_challenge_method
等をパラメーターとして認証リクエストをしている動きが見えます。(フロー図の03〜04)
その後、認可エンドポイントからリダイレクトレスポンスを受け取り、ログインエンドポイントへリダイレクトしている動きが見えます。(フロー図の05〜06)
つまり、 Auth.federatedSignIn
(&ブラウザのリダイレクト)が次のような処理を開発者が気にしなくていいように隠蔽してくれています。
そして、認証フローを理解していると次の疑問が出てきます。
「それじゃあ、トークンリクエストはいったいどこの誰がやっているのだろう?」
これは、Amplifyのソースを追っていくとわかります。 Amplify.configure
がやってくれています。
これも、サンプルアプリケーションとブラウザの開発者ツールを使ってAmplifyの動きを追ってみます。
今のままだと、アクセスした瞬間に onLoad()
が走ってしまうので、 viws/index.ejs
のbodyを書き換えて、 onLoad()
の実行をいったん止めます。 そして、 Amplify.configure
にブレークポイントを設定します。
<!--<body onload="onLoad()">--> <body>
ブレークポイントをしかけた上で、consoleから手動で onLoad()
を実行します。
そして Amplify.configure
からステップインで処理を追っていくと、セッションストレージから state
と code_verifier
が削除されている動きが見えます。(フロー図の12)
そして、Cognitoトークンエンドポイントに対して、 code
, code_verifier
等をパラメーターとしてトークンリクエストが投げられて。(フロー図の13)
トークンレスポンスを受け取るという動きも見えます。(フロー図の14)
ブレークから復帰して最後まで進めると、最終的にはローカルストレージに IDトークン 、アクセストークン が保存されていることがわかります。
つまり、 Amplify.configure (&ブラウザのリダイレクト)が次のような処理を開発者が気にしなくていいように隠蔽してくれています。
結論として、これまで説明したような認証フローの処理を Amplifyがうまいことやってくれる ので、 プログラム開発者は認証フローをほとんど意識することなく、 Auth.federatedSignIn
をするだけで認証機能を実装できるというわけです。 スゴイですね。
終わりに
知らなくても困らないけど、知っているとおもしろいかもしれない Amplify の認証の裏話について語りました。
実際この認証フローのアプリケーション側を自分で実装しようとするととても面倒くさいので、 Amplify が隠蔽してうまいことやってくれるのはとてもうれしいですね。
認証部分はぜひAmplify等のライブラリを使って楽をしましょう。
ちなみに、クラスメソッドでは認証を楽にするSaaSサービス、 Auth0 の取り扱いもございます。
認証でお困りの際には、お気軽にクラスメソッドまでお問い合わせください。