ログイン画面表示方法の違いは思った以上に大きかった件

本稿はJCB Tech Blog Advent Calendar 2022の12月25日の記事です。

JCBデジタルソリューション開発部アーキテクトチームの長沼です。

JDEPではID管理にOktaを利用しており、 開発者のID管理をOkta Workforce Identity Cloud、アプリ利用者のID管理をOkta Customer Identity Cloud(旧Auth0、以下CIC) と使い分けています。

今回はSingle Page Application(以下SPA)からCICを使うためのクライアントライブラリであるSPA SDKで面白い気づきがありましたので、ご紹介したいと思います。

TL;DR

  • SPA SDKを用いてログイン画面を呼び出すメソッドは2種類あり、 リダイレクト(画面遷移)によるloginWithRedirectと、ポップアップ(別ダイアログ表示)によるloginWithPopup
  • loginWithPopupを用いた認証認可では、認可コード(Authorization Code)の伝搬範囲をブラウザ(クライアント)内に留めることが可能。

前提とする構成

利用者がブラウザでSPAを表示しログイン(CICで認証認可)を行う場合、基本的には次のような流れとなります。

構成要素およびログイン処理時の関係

  1. 利用者がSPA本体を格納したWebサーバにブラウザでアクセスします。
  2. するとWebサーバからブラウザにSPAがダウンロードされ表示されます。
  3. 利用者はブラウザ上に表示されたSPAのログインボタンを押下し、ログインを行います。
  4. するとCICのログイン画面がブラウザ上に表示されます。
  5. このログイン画面に対して利用者はIDとPWを入力します。
  6. 入力されたIDとPWがCICで検証され、ブラウザ上のSPAとCICの間で認証認可処理が行われます。

loginWithRedirect と loginWithPopup の見た目の違い

loginWithRedirectloginWithPopupを使った場合のログイン画面表示の流れは、それぞれ次のようになります。 なお各画面は公式のReactサンプルのものを例として用いています。

画面表示の違い

loginWithRedirectを使った場合、ID/PWを入力するログイン画面は同一ブラウザウィンドウ上に表示されます。 そしてID/PWによる認証が完了すると、また同じブラウザウィンドウに元のSPAがログイン状態で表示されます。

一方でloginWithPopupを使った場合、別のポップアップダイアログ(別ブラウザウィンドウ)としてログイン画面が表示されます。 このとき元々SPAを表示していたブラウザは表示されたままで、例えば今回のサンプルの実装では待機状態が表示された状態となります。 そしてログイン画面にID/PWを入力し認証が完了すると、ポップアップは自動的にクローズされ、元のSPAがログイン状態に表示更新されます。

loginWithRedirect と loginWithPopup の処理の違い

処理の流れに着目してみると、実はloginWithRedirectloginWithPopupは見た目の挙動が違うだけではないことに気づきます。

具体的にはAuthorization Code Flow ベースで認証認可を行うとき、利用者によるログイン以降のそれぞれの処理の流れは以下のようになります(説明の都合上、一部処理フローは省略しています)。

処理の違い

図左側loginWithRedirectは画面遷移となるため認可コード(Authorization Code)のコールバック時にSPA取得のためWebサーバへの通信が発生してしまいます(図中左側の赤矩形部分)。このコールバックURLには認可コードが付いているため、認可コードも結果的にWebサーバに送られてしまいます。
図右側loginWithPopupでは、コールバック時に表示していたブラウザウィンドウが閉じられてSPAを表示していたブラウザに戻るのみのため、クライアント側で処理が完結します。結果、Webサーバへの通信が発生しません(図中右側の赤破線分)。

よってSPAのみの認証認可でよい場合であっても(Webサーバは認証認可する必要がない場合であっても)、loginWithRedirectを用いるとWebサーバにも認可コードが送られてしまうことになります。 SPAの実体を格納するWebサーバのためセキュリティ上のリスクは必ずしも高くないとはいえ、最小権限の原則に照らせば好ましいことではありません。 よってloginWithPopupに比べるとloginWithRedirectはリスクが高い実装となりやすい、と見ることができます。

一方で、loginWithPopupの単一ブラウザウィンドウで完結しないという点はデメリットにもなりえます。

これら2つのメソッドのどちらを採用するかは、セキュリティとユーザビリティやプロダクト仕様等とのトレードオフで決めることになると思います。 とはいえ2種類の方法がSDKで実装済みで選択肢としてあることは、アプリを実装する上では独自実装が必要なく嬉しいですね。

さいごに

今回ご紹介したようにCICは、Auth0時代から蓄積されたクライアント側のライブラリやSDKも充実しています。 こうしたライブラリ・SDKを使うことで、サービス利用によるID管理基盤の構築運用から開放されるばかりでなく、 アプリの実装自体が効率的に行えることもCICの魅力と感じました。
これからも、こうした気付きがあれば随時発信していきたいと思います。

最後になりますが、JCBでは我々と一緒に働きたいという人材を募集しています。 詳しい募集要項等については採用ページをご覧下さい。

Merry X'mas!


本文および図表中では、「™」、「®」を明記しておりません。
記載されているロゴ、システム名、製品名は各社及び商標権者の登録商標あるいは商標です。

©JCB Co., Ltd. 20︎21