シングルページ・アプリ
IBM Cloud® App ID を使用すると、シングルページ・アプリケーション (SPA) に許可と認証を簡単に追加できます。 SPA はブラウザーだけで実行されます。ユーザーが管理するバックエンドは存在せず、アプリケーションの使用中にページを再ロードする必要もありません。 SPA で使用される一般的なフレームワークには、 Angular および Reactがあります。
アプリのために管理しているバックエンドがありますか? その場合、SPA のフローは適していません。 Web アプリのフローを試してください。
フローについて
これは現在のSPAの業界標準だが、OAuthワーキンググループはいくつかのセキュリティ上の懸念から、暗黙フローの使用を推奨していない。 彼らのアドバイスに基づき、 App ID、 PKCEでAuthorization Codeフローを使用するように設定されている。
- ユーザーがシングルページ・アプリケーションにログインしようとします。
- App ID SDK が許可要求のコード・ベリファイヤーを作成します。これは平文バージョンのコード・チャレンジです。 クライアントは、許可要求と一緒に、コード・チャレンジと、チャレンジのエンコードに使用するチャレンジ・メソッドを送信します。
- 認証フローが、App ID によって新しいウィンドウで開始されます。
- ユーザーは、認証を行う ID プロバイダーを選択し、サインイン・プロセスを実行します。
- アプリケーション上の App ID SDK が認可コードを受け取ります
- その後、SDK が、認可コードおよびコード・ベリファイヤーと一緒に XHR 要求を App ID トークン・エンドポイントに送信して、アクセス・トークンと識別トークンを取得します。
Cloud Directory に SSO を使用していますか? App ID Client SDK を使用すると、ユーザーが明示的にサインインしなくても、新しいトークンのペアを自動的に取得できます。 詳しくは、サイレント・ログインを参照してください。
なぜ許可コード + PKCE を使用するのですか?
シングルページ・アプリケーションは、その性質上、シークレットを安全に保管できません。 OAuth 2.0 の許可コード・フローの変化形である「許可 + PKCE」フローは、シークレットの代わりにワンタイム・コード・ベリファイヤーとチャレンジを使用することで、この問題を解決しています。 ベリファイヤーとチャレンジにより、許可エンドポイントを呼び出したエンティティーと、トークン・エンドポイントを呼び出したエンティティーが同じであることが確認されます。 つまり、攻撃者が許可サーバーにトークンを要求するには、コード・ベリファイヤーも知っていなければなりません。
暗黙フローは現在の業界標準ですが、セキュリティーの欠陥がいくつか見つかっています。 例えば、暗黙フローではリダイレクト URI を使用してトークンを取得できます。「許可 + PKCE」のフローでは代わりに XHR 要求を使用することでこの問題を回避しています。 これらのセキュリティー欠陥のために、暗黙フローは以下の理由で推奨されなくなり、また、安全とも見なされなくなりました。
-
暗黙フローは URL の一部として (照会パラメーターとして、またはハッシュ・フラグメントに入れて) トークンを返します。 そのため、トークンは横取りされてアクセスされる可能性があります。 トークンがユーザーのブラウザーの履歴またはログに保存される可能性もあります。 履歴またはログがクラウド・サービスに保管され、複数のデバイスに送信される可能性もあり、これもリスクを高めます。
-
暗黙的フローは リダイレクトURI攻撃の影響を受けやすい。これは、攻撃者が承認 されたリダイレクトURIを自分の好きな宛先に置き換える可能性があることを意 味する。 リダイレクト URI 攻撃が行われると、ユーザーは変更されたリンクに従ってクライアントを許可することになります。 許可後、攻撃者の URI にリダイレクトされるので、攻撃者がユーザーの正当なトークンを取得できます。
前述の例は、重大な問題のほんの一部にすぎません。 詳細については、 OAuth 2.0 セキュリティのベストプラクティスを参照してください。
開始前に
開始する前に、以下の前提条件を満たしていることを確認してください。
- App ID サービスのインスタンス。
- App ID サービス・ダッシュボードで設定されたリダイレクト URI。
- シングルページ・アプリケーション。 まだアプリケーションはないけれどもフローを試したいという場合は、App ID ダッシュボードの概要ページからサンプル・アプリケーションをダウンロードしてください。
GUI を使用したアプリケーション資格情報の作成
アプリケーションを App ID に接続するには、資格情報を使用します。 資格情報を作成するには、アプリを App ID に登録します。
SPA の資格情報に入れて返されるクライアント・シークレットはありません。 「許可 + PKCE」フローではシークレットは不要です。 SPA フローでは正規の Web アプリ資格情報は使用できません。
- 使用するリージョンの IBM Cloud ダッシュボードにサインインします。
- **「アプリケーション」タブにナビゲートし、「アプリケーションの追加」**をクリックします。
- 名前をアプリケーションに付けます。
- **「タイプ」ドロップダウンから「シングルページ・アプリケーション (Single-page application)」**を選択します。
- 保存 をクリックします。
- 表で、**「資格情報の表示」**をクリックして、以下の構成に必要な情報を参照します。
API を使用したアプリケーション資格情報の作成
アプリケーションを App ID に接続するには、資格情報を使用します。 資格情報を作成するには、アプリを App ID に登録します。
SPA の資格情報に入れて返されるクライアント・シークレットはありません。 「許可 + PKCE」フローではシークレットは不要です。 SPA フローでは正規の Web アプリ資格情報は使用できません。
-
に対し、以下の投稿依頼を行う。 /management/v4/
/アプリケーション エンドポイント。curl -X POST \ https://us-south.appid.cloud.ibm.com/management/v4/<tenantID>/applications/ \ -H 'accept: application/json' \ -H 'Authorization: Bearer <IAMToken>' \ -H 'Content-Type: application/json' \ -d '{"name": "MySampleSPA", "type": "singlepageapp"}'
応答の例:
{ "clientId": "<clientID>", "tenantId": "<tenantID>", "name": "MySampleSPA", "oAuthServerUrl": "https://us-south.appid.cloud.ibm.com/oauth/v4/<tenantID>", "type": "singlepageapp" }
JavaScript SDK の構成
アプリケーション内に SDK をインストールするには、以下の手順を参考にしてください。
-
コマンド・プロンプトを使用して、アプリケーションが含まれているディレクトリーに移動します。
-
NPM を使用するか、またはメイン HTML ファイルに CDN のリンクを作成して、App ID サービスをインストールします。
-
NPM を使用するには、次のコマンドを実行します。
npm install ibmcloud-appid-js
-
CDN を追加するには、次のリンクをメイン HTML ファイルに追加します。
<script src="https://cdn.appid.cloud.ibm.com/appid-0.3.0.min.js"></script>
-
-
クライアント ID とディスカバリー・エンドポイントをアプリに追加して、SDK を初期化します。
const appID = new AppID(); await appID.init({ clientId: '<spaClientID>', discoveryEndpoint: '<wellKnownEndpoint>' });
-
アプリケーション・コード内で、ログイン・ボタンの構成の後に、
signin
の呼び出しを追加します。 ユーザーに資格情報の入力を求めるポップアップ・ウィンドウが開きます。 認証に成功すると、この画面は閉じ、ユーザーは認証されます。const tokens = await appID.signin();
サイレント・ログインの構成
Cloud Directory の SSO を有効にすると、サイレント・ログインを使用して、再認証せずにユーザーの新しいトークンを自動的に取得できます。 サイレント・ログインを有効にするには、以下の手順を参考にしてください。
SPA フローではリフレッシュ・トークンは返されません。
-
App ID ダッシュボードで、**「Cloud Directory」>「シングル・サインオン (Single Sign-on)」**にナビゲートします。
-
**「シングル・サインオンを有効にする」を「使用可能」**に切り替えます。
-
保存 をクリックします。
-
以下のコードをアプリケーションに追加します。 サイレント・ログインが失敗した場合にログイン・ボタンを表示するようにアプリケーションを構成します。
const tokens = await appID.silentSignin(); if (!tokens) { document.getElementById('login').addEventListener('click', async () => { const tokens = await appID.signin(); }); }