メインコンテンツへスキップ
本ドキュメントはSPA + APIアーキテクチャシナリオの一部で、Angular 2でSPAを実装する方法を説明します。実装したソリューションについての情報は、シナリオを参照してください。 Angular 2でのSPA実装で使用する全ソースコードは、こちらのGitHubリポジトリでご覧いただけます。

1.構成

アプリケーションには特定の構成情報が必要になります。残りの実装作業に進む前に、さまざまな構成値を入れるAuthConfigインターフェイスを作成してください。このインターフェイスは、auth0-variables.tsというファイルに入れます。

2.ユーザーの認可

認可サービスの作成

ユーザー認証に必要なタスクを管理・調整する最善の方法は、再利用可能なサービスを作成することです。これにより、アプリケーション全体でそのメソッドを呼び出せるようになります。auth0.jsWebAuthオブジェクトのインスタンスは、サービスで作成できます。
このサービスには、認証を処理するためのメソッドがいくつかあります。
  • login :ユニバーサルログインを開始するauthorizeをauth0.jsから呼び出す
  • handleAuthentication :URLハッシュで認証結果を探し、auth0.jsのparseHashメソッドで処理する
  • setSession :ユーザーのアクセストークン、IDトークン、およびアクセストークンの有効期限を設定する
  • logout :ブラウザーストレージからユーザーのトークンを削除する isAuthenticated:アクセストークンの有効期限が切れたかどうかを確認する

認証結果の処理

ユーザーがユニバーサルログイン経由で認証し、アプリケーションにリダイレクトで戻されると、認証情報はURLのハッシュフラグメントに含まれます。AuthServicehandleAuthenticationメソッドが、ハッシュの処理を行います。 アプリのルートコンポーネントでhandleAuthenticationを呼び出すことで、ユーザーがアプリにリダイレクトで戻された後、アプリを最初に読み込む際、認証のハッシュフラグメントを処理できるようにします。

コールバックコンポーネントの追加

ユニバーサルログインを使用すると、ユーザーはアプリケーションからAuth0がホストするページに移動します。そして、正常に認証された後、クライアント側セッションがセットアップされた状態のアプリケーションに戻ります。 ユーザーを戻す場所はアプリケーション内の任意のURLに設定できますが、認証に成功したユーザーが戻る中心的な場所として専用のコールバックルートを作成することを推奨します。コールバックルートを単一にする利点は主に2つあります。
  • 複数の(時として未知の)コールバックURLを許可リストに登録する必要がなくなる
  • アプリケーションがクライアント側セッションを設定する間、読み込み中のインジケーターを表示する場所になる
CallbackComponentというコンポーネントを作成して、読み込み中インジケーターを自動入力します。
この例では、assetsディレクトリで何らかの読み込み中スピナーを使えることが想定されています。デモはダウンロード可能なサンプルをご覧ください。 認証後、ユーザーは短時間だけ、読み込み中インジケーターが表示された/callbackルートに移動します。この間にクライアント側セッションが設定され、完了したら/homeルートにリダイレクトされます。

3.ユーザープロファイルの取得

トークンから情報を抽出する

このセクションでは、アクセストークンと/userinfoエンドポイントを使って、ユーザー情報を取得する方法について説明します。ライブラリーを使って、単にIDトークンをデコードすることもできます(必ず先に検証をしてください)。結果は同じです。他のユーザー情報が追加で必要な場合は、Management APIの使用を検討してください。
ユーザーのプロファイルを取得するには、既存のAuthServiceクラスを更新します。ユーザーのアクセストークンをローカルストレージから抽出するgetProfile関数を追加し、それをuserInfo関数に渡してユーザー情報を取得します。
これで、ユーザーに関する情報を取得して表示したい任意のサービスからこの関数をすぐに呼び出せるようになります。 たとえば、新しいコンポーネントを作成して、ユーザーのプロファイル情報を表示することができます。
このコンポーネントのテンプレートは以下のようなものになります。

4.スコープに基づいた条件付きUI要素の表示

認可プロセスで、ユーザーに付与された実際のスコープをすでにローカルストレージに保存しています。authResultで返されるscopeが空でない場合、ユーザーには最初に要求されたものと異なる一連のスコープが発行されたことを意味するので、authResult.scopeを使ってユーザーに付与されたスコープを判断する必要があります。 authResultで返されるscopeが空の場合は、要求されたすべてのスコープがユーザーに付与されたことを意味するので、要求されたスコープを使用してユーザーに付与されたスコープを判断することができます。 この確認を行うために先ほど書いたsetSession関数のコードがこちらです。
次に、ユーザーが特定のスコープを付与されているかどうかを判断するために呼び出すことができる関数をAuthServiceクラスに追加する必要があります。
このメソッドは、特定のUI要素を表示すべきかどうかを判断するために呼び出すことができます。例として、approve:timesheetsスコープを持つユーザーにのみ [Approve Timesheets(タイムシートの承認)] リンクを表示したい場合を考えます。下のコードでは、リンクを表示すべきか否かを判断するためにuserHasScopes関数の呼び出しを追加します。

ルートの保護

ユーザーに正しいスコープが付与されていない場合にユーザーがルートにナビゲートされないよう、ルートを保護する必要もあります。このために、新しいScopeGuardServiceサービスクラスを追加することができます。
追加したら、ルートの構成時に使用して、ルートを有効にしてよいかどうかを判断します。以下のapprovalルートの定義では、新しいScopeGuardServiceが使用されています。

5.APIの呼び出し

angular2-jwtモジュールは、APIに対する要求にを自動的にアタッチするために使用できます。これは、AngularのHttpクラスのラッパーであるAuthHttpクラスを提供することで実現されます。 angular2-jwtをインストールします。
angular2-jwtの構成値を含むファクトリ関数を作成して、アプリケーションの@NgModuleproviders配列に追加します。ファクトリ関数には、ローカルストレージからaccess_tokenを取得するtokenGetter関数が必要です。
angular2-jwtが構成されたら、AuthHttpクラスを使用してアプリケーションの任意の場所からAPIを安全に呼び出すことができます。そのためには、AuthHttpを必要な任意のコンポーネントまたはサービスに注入し、Angularの標準Httpクラスと同様に使用します。

6.アクセストークンの更新

ユーザーのアクセストークンの更新には、Angular SPAのアップデートが必要です。auth0.jsからcheckSessionメソッドを呼び出すメソッドをAuthServiceに追加します。更新できたら、既存のsetSessionメソッドを使用してローカルストレージに新しいトークンを設定します。
AuthServiceクラスにscheduleRenewalというメソッドを追加して、認証をサイレント更新すべき時間をセットアップします。以下の例では、実際のトークンが期限切れになる30秒前に更新されるようにセットアップしています。また、Observableからサブスクリプションを解除するunscheduleRenewalというメソッドも追加します。
最後に、スケジュールの更新を開始する必要があります。そのためには、ページの読み込み時に実行されるAppComponent内のscheduleRenewalを呼び出します。これは、ユーザーの明示的なログインかサイレント認証のいずれかの認証フロー後に毎回発生します。

リフレッシュトークンローテーション

ブラウザーにおけるユーザーのプライバシー管理についての最近の進歩は、サードパーティクッキーへのアクセスを防ぐことでユーザーエクスペリエンスに悪影響を与えています。Auth0では、「リフレッシュトークンのローテーション」の使用を推奨しています。リフレッシュトークンローテーションは、SPAでリフレッシュトークンを安全に使用するためのセキュリティ方式であり、リソースにアクセスするエンドユーザーに、ITPのようなブラウザーのプライバシー保護技術に煩わされないシームレスなユーザーエクスペリエンスを提供します。