AmplifyでCognitoのマネージドログインを利用した認証を最低限のReact実装で動かしてみて動作を理解する
このブログは、昔書いたこのブログを、現状のライブラリやドキュメント、Cognitoのマネージドログイン機能のUIに合わせて書き直したものです。
はじめに
Amplifyを使うと、Cognitoを利用して簡単に認証機能を作れて便利です。
Cognitoにマネージドログイン機能が導入されたことで、より活用しやすくなったと思います。
マネージドログイン機能を利用したログインのイメージ動画を作成したのでこちらをご覧ください。
実装上の話をすると、ログインUI用の別URLにジャンプする動作をするという関係上、マネージドログイン機能を利用する場合、 認証フローが大きく異なります 。
その認証フローが大きく変わるという部分を Amplifyがうまいことやってくれて 、 プログラム開発者はほとんど意識することなく認証機能を実装できます。スゴイですね!
Amplifyの公式ドキュメントに、ReactでCognitoのマネージドログイン機能を利用してFacebookログインやGoogleログインを実装するサンプルがあります。 詳しくはこちらを御覧ください。
動くものを作りたいだけであれば、ここまで読んでいただければ大丈夫です。
ありがとうございました。
ここから先は、「 うまいことってなんなんだよ。全然納得できない。具体的に何をどうしてるんだよ。 」 みたいなことを考えてしまう私みたいなひねくれ者のために、
知らなくても困らないけど、知っているともっと楽しめるかもしれない、
AmplifyとCognitoのマネージドログインがどんな認証フローをとっているのか? そして、 具体的に何をうまいことやってくれているのか? という話をします。
前提
以前のブログは生javascriptで書かれていましたが、今回はReactを使って書き直しています。
このブログではReact自体の説明はしません。Reactについて知りたい方は公式ドキュメントを参照してください。
サンプルプログラムを動かす場合、次のコマンドが利用できるようにインストールをしておいてください。
$ node --version
v20.13.1
$ npm --version
10.9.2
$ aws --version
aws-cli/2.22.6 Python/3.12.6 Darwin/23.6.0 exe/x86_64
$ curl --version
curl 8.7.1 (x86_64-apple-darwin23.0) libcurl/8.7.1 (SecureTransport) LibreSSL/3.3.6 zlib/1.2.12 nghttp2/1.61.0
サンプルプログラム置き場
今回作成したプログラムはGitHubで公開しています。 実際に動かしてみたい方はこちらから git clone
してください。
Cognito環境の構築
まずは git clone
して環境一式をGitHubから取ってきます。
$ git clone https://github.com/rednes/cognito-react-example-for-external-idp
$ cd cognito-react-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ユーザープールのマネジメントコンソール画面を開いてください。
CognitoReactExampleUsers という名前のユーザープールができているので開きます。
左側のメニューの ドメイン名 を選択して、 アクション > Cognitoドメインの作成 を選択してください。
ドメインのプレフィックス を入力してください。 ドメインのプレフィックスは後で利用するのでメモしておいてください。
ブランディングバーション は、マネージドログインを選択してください。
以上でCognitoの環境構築は終了です。
アプリケーションの設定
アプリケーションの設定ファイルを、Cognitoの環境とあわせた値に変更します。
/src/amplifyConfigure.example.ts ファイルを /src/amplifyConfigure.ts
にコピーして、さきほどメモしたドメインのプレフィックスを COGNITO_DOMAIN_PREFIX
に入力してください。
COGNITO_USER_POOL
等の値は、さきほど実行した npm run cfn:describe
コマンドで確認できるのでこれも入力してください。
$ npm run cfn:describe
---------------------------------------------------------
| DescribeStacks |
+------------------------+------------------------------+
| CognitoRegion | ap-northeast-1 |
| CognitoUserPool | ap-northeast-1_XXXXXXXXX |
| CognitoUserPoolClient | XXXXXXXXXXXXXXXXXXXXXXXXXXX |
+------------------------+------------------------------+
import { ResourcesConfig } from "aws-amplify";
const COGNITO_REGION = "ap-northeast-1";
const COGNITO_USER_POOL = "ap-northeast-1_XXXXXXXXX";
const COGNITO_USER_POOL_CLIENT = "dummy";
const COGNITO_DOMAIN_PREFIX = "dummy";
export const config: ResourcesConfig = {
Auth: {
Cognito: {
userPoolId: COGNITO_USER_POOL,
userPoolClientId: COGNITO_USER_POOL_CLIENT,
loginWith: {
oauth: {
domain: `${COGNITO_DOMAIN_PREFIX}.auth.${COGNITO_REGION}.amazoncognito.com`,
scopes: ["openid"],
redirectSignIn: ["http://localhost:3000/"],
redirectSignOut: ["http://localhost:3000/"],
responseType: "code",
},
},
},
},
};
次に、ローカルでReactアプリケーションを起動するために、次のコマンドを実行してjavascriptパッケージをインストールしてください。
$ npm install
次のコマンドを実行して、待機状態になれば成功です。 http://localhost:3000
でアクセスできるReactアプリケーションができました。
$ npm run dev
> cognito-react-example-for-external-idp@0.0.0 dev
> vite --port 3000
VITE v6.0.2 ready in 95 ms
➜ Local: http://localhost:3000/
マネージドログインを利用したログインの流れを確認してみる
ブラウザから http://localhost:3000
にアクセスすると、こんな感じのシンプルなボタンがあるだけの画面が表示されます。
ここで Open Managed Login ボタンをクリックすると、Cognitoのマネージドログイン画面に飛びます。
ユーザー登録の説明は省いて、すでにユーザーは登録済みという前提で進めます。
Email/Passwordを入力してサインインします。
そうすると、元のページに戻ってユーザー認証が完了し、Cognitoの発行したトークンがベロっと画面に表示されるというアプリケーションです。
Sign Outボタンを押すと、サインアウトされてトークンの表示もなくなります。
ただこれだけのシンプルなReactアプリケーションです。
それではコードを読んでいきましょう。 60行程度なので、すぐ読めると思います。
コードの解説
src/App.tsx
12行目の Amplify.configure
で設定ファイルから、Amplifyの初期設定をしています。
19行目の useEffect
で、初回レンダリング時に getCurrentUser
, fetchAuthSession
を使ってユーザー情報を取得しています。取得できたら useState
でその情報を保持しています。
40行目の onClick
で、 Open Managed Loginボンタンが押された時に、 signInWithRedirect
を実行するようにしています。
このファンクションが、 Cognitoのマネージドログイン画面へリダイレクトしている処理 の正体です。
52, 53行目で取得してuseStateで保持していたユーザー情報をpreタグでベロっと表示しています。
こんな感じのReactアプリケーションです。
ここで何が言いたいかというと、プログラムを書く際に 明示的に書いてる認証処理 は40行目の signInWithRedirect
だけということです。
これ以外ほぼ何もせずに認証処理が実装できています 。スゴイですね!
プログラムが具体的にイメージできたところで、そろそろ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
本筋から外れるので、本ブログでは 各フローについての詳細までは立ち入りません 。
どういう場合にどのフローを選択するかだけざっと説明します。
- 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
コマンドを実行することで、この認可エンドポイントに対して認証リクエストを投げることができます。
$ COGNITO_REGION=ap-northeast-1
$ COGNITO_USER_POOL_CLIENT=<<YOUR_COGNITO_CLIENT_ID>>
$ COGNITO_DOMAIN_PREFIX=<<YOUR_COGNITO_DOMAIN_PREFIX>>
$ COGNITO_DOMAIN=${COGNITO_DOMAIN_PREFIX}.auth.${COGNITO_REGION}.amazoncognito.com
$ curl -i "https://${COGNITO_DOMAIN}/oauth2/authorize?response_type=code&client_id=${COGNITO_USER_POOL_CLIENT}&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
を指定します。
- 認可コードを返すリダイレクト先のURLを指定します。今回は、
- state
- Cognitoがクライアントにリダイレクトして戻るときに、この値を含めるようになります。オプション値ですが、CSRF攻撃を防ぐために設定することが強く推奨されています。
- scope
- スコープを指定します。OIDC認証をする場合、
openid
の指定が必須です。今回はopeind
を指定します。
- スコープを指定します。OIDC認証をする場合、
実際にこのリクエストを投げてみましょう。
そうすると、 302リダイレクト のレスポンスが返ってきて、 Locationレスポンスヘッダー にリダイレクト先のURLが示されていることがわかります。
HTTP/2 302
location: https://<<YOUR_COGNITO_DOMAIN_PREFIX>>.auth.ap-northeast-1.amazoncognito.com/login?client_id=h10utk89qfrujrmc1h2lep8bd&redirect_uri=http://localhost:3000&response_type=code&scope=openid&state=xyz
また、LocationのURLから、リダイレクト先はログインエンドポイントであることがわかります。
このログインエンドポイントというのが、いわゆるCognitoの マネージドログイン画面のURL のことです。
次にこのリダイレクト先のURLへブラウザを使ってアクセスしてみます。(フロー図の05〜08)
そうするとこのようにCognitoのログイン画面が表示されます。
ログインするとlocalhostへリダイレクトされてくるので、ローカルサーバーがリクエストを受け取らないように Reactアプリケーションは終了 しておいてください。
E-mail/Passwordを入力してログインすると、Cognitoからリダイレクトレスポンスが返ってきます。
リダイレクトレスポンスは次のような形をしています。
http://localhost:3000/?code=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX&state=xyz
state
には認証リクエストで指定したxyzが入っています。 通常CSRF攻撃を防ぐため、認証リクエストで送信した state
をアプリケーション側で保持しておきます。そして、リダイレクトで返ってきた state
と一致しているかをアプリケーション側でチェックします。
code
の値に入っているものが 認可コード です。 認可コード はトークンリクエストの際に必要です。
次に IDトークン ・ アクセストークン の取得処理です。
トークンエンドポイントに対してトークンリクエストをやってみます。(フロー図の11〜12)
Callbackで受け取った 認可コード を AUTHORIZATION_CODE
環境変数に格納すると、
次のような curl
コマンドを実行することで、トークンエンドポイントに対してトークンリクエストを投げることができます。
$ AUTHORIZATION_CODE=<<YOUR_AUTHORIZATION_CODE>>
$ COGNITO_REGION=ap-northeast-1
$ COGNITO_USER_POOL_CLIENT=<<YOUR_COGNITO_CLIENT_ID>>
$ COGNITO_DOMAIN_PREFIX=<<YOUR_COGNITO_DOMAIN_PREFIX>>
$ COGNITO_DOMAIN=${COGNITO_DOMAIN_PREFIX}.auth.${COGNITO_REGION}.amazoncognito.com
$ curl -X POST \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=authorization_code" \
-d "client_id=${COGNITO_USER_POOL_CLIENT}" \
-d "scope=openid" \
-d "redirect_uri=http://localhost:3000" \
-d "code=${AUTHORIZATION_CODE}" \
"https://${COGNITO_DOMAIN}/oauth2/token"
パラメーターの項目と設定値について説明します。
- grant_type
authorization_code
,refresh_token
またはclient_credentials
を指定します。今回はAuthorization code grantに沿ってトークンを要求しているので、authorization_code
を指定します。
- client_id
- CognitoユーザープールのクライアントIDを指定します。
- scope
- スコープを指定します。OIDC認証をする場合、
openid
の指定が必須です。今回はopeind
を指定します。
- スコープを指定します。OIDC認証をする場合、
- 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が何なのかを定義しています。
export const config: ResourcesConfig = {
Auth: {
Cognito: {
userPoolId: COGNITO_USER_POOL,
userPoolClientId: COGNITO_USER_POOL_CLIENT,
loginWith: {
oauth: {
domain: `${COGNITO_DOMAIN_PREFIX}.auth.${COGNITO_REGION}.amazoncognito.com`,
scopes: ["openid"],
redirectSignIn: ["http://localhost:3000"],
redirectSignOut: ["http://localhost:3000"],
responseType: "code",
},
},
},
},
};
特に重要なパラメーターの項目と設定値について説明します。
- Auth.Cognito.userPoolClientId
- CognitoユーザープールのクライアントIDを指定します。認証リクエストやトークンリクエストする際に、クライアントIDとして利用されます。
- Auth.Cognito.loginWith.oauth.domin
- 認可エンドポイント等、各エンドポイントにアクセスする際のCognitoのエンドポイントのドメイン名として利用されます。
- Auth.Cognito.loginWith.oauth.scopes
- スコープを指定します。OIDC認証をする場合、
openid
の指定が必須です。今回はopeind
を指定しています。
- スコープを指定します。OIDC認証をする場合、
- Auth.Cognito.loginWith.oauth.redirectSignIn
- 認証リクエストやトークンリクエストをする際のリダイレクト先URLを指定します。今回は、
http://localhost:3000
を指定しています。
- 認証リクエストやトークンリクエストをする際のリダイレクト先URLを指定します。今回は、
- Auth.Cognito.loginWith.oauth.responseType
code
またはtoken
を指定します。Authorzation code grantフローを採用する場合、code
を指定します。Implicit grantフローを採用する場合、token
を指定します。今回は、Authorzation code grantフローを採用したいので、code
を指定します。
ちなみに、Auth.Cognito.loginWith.oauth.redirectSignIn
はCognitoのアプリケーションクライアントのマネージドログインページ編集画面で設定する コールバックURL と一致していないと、Cognito側が受け付けてくれません。
また、 Auth.Cognito.loginWith.oauth.responseType
で code
を指定する場合は、 Authorzation code grant フローを採用することになります。
その場合、Cognitoのこの画面で Authorization code grant(認証コード付与) を指定する必要があります。
token を指定する場合は、 Implicit grant フローを採用することにります。その場合、 Implicit grant(暗黙的な付与) を指定する必要があります。
また、 Auth.Cognito.loginWith.oauth.scopes
で指定できるスコープは、Cognitoのこの画面で許可されている OpenID Connect のスコープ に限ります。
Amplifyの動作
PKCEを併用するAuthorization code grant フローのシーケンス図を再掲します。
Amplifyが何をうまいことやっているのか明らかにするために、
先ほど構築したサンプルアプリケーションとブラウザの開発者ツールを使ってAmplifyの動きを追ってみます。
signInWithRedirect
にブレークポイントをしかけた上で、Open Managed Loginボタンをおして signInWithRedirect
を実行し、ステップインで処理を追っていきます。
そうすると、ローカルストレージに state
と code_verifier
を保存している動きが見えます。(フロー図の02)
その後、ブレークから復帰してCognitoのマネージドログイン画面まで遷移すると、Cognitoの認可エンドポイントに対して、 state
, code_challenge
, code_challenge_method
等をパラメーターとして認証リクエストをしている動きが見えます。(フロー図の03〜04)
その後、認可エンドポイントからリダイレクトレスポンスを受け取り、 ログインエンドポイントへリダイレクト している動きが見えます。(フロー図の05〜06)
つまり、 signInWithRedirect
(&ブラウザのリダイレクト)が次のような処理を開発者が気にしなくていいように隠蔽してくれています。
そして、認証フローを理解していると次の疑問が出てきます。
「それじゃあ、 トークンリクエストはいったいどこの誰がやっているのだろう?」
これは、Amplifyのソースを追っていくとわかります。 Amplify.configure
がやってくれています。
これも、サンプルアプリケーションとブラウザの開発者ツールを使ってAmplifyの動きを追ってみます。
ログイン前にあらかじめ Amplify.configure
へブレークポイントを設定しておきます。
ブレークポイントを設定したうえで、ログインしてリダイレクトで戻ってくると、 Amplify.configure
の実行時に止まります。
この時点では、URLに 認可コード も含まれているし、ローカルストレージに state
と code_verifier
も残っています。
そして Amplify.configure
からステップインで処理を追っていくと、ローカルストレージから state
と code_verifier
が削除されている動きが見えます。(フロー図の12)
そして、Cognitoトークンエンドポイントに対して、 code
, code_verifier
等をパラメーターとして トークンリクエスト が投げられて。(フロー図の13)
トークンレスポンスを受け取るという動きも見えます。(フロー図の14)
ブレークから復帰して最後まで進めると、最終的にはローカルストレージに IDトークン 、アクセストークン が保存されていることがわかります。
つまり、 Amplify.configure(&ブラウザのリダイレクト)が次のような処理を開発者が気にしなくていいように隠蔽してくれています。
結論として、これまで説明したような認証フローの処理を Amplifyがうまいことやってくれる ので、 プログラム開発者は認証フローをほとんど意識することなく、 signInWithRedirect
するだけで認証機能を実装できるというわけです。 スゴイですね。
おわりに
知らなくても困らないけど知っているとおもしろいかもしれない Amplify の認証の裏話について語りました。
実際この認証フローのアプリケーション側を自分で実装しようとするととても面倒くさいので、 Amplify が隠蔽してうまいことやってくれるのはとてもうれしいですね。
認証部分はぜひAmplify等のライブラリを使って楽をしましょう。