Skip to main content
このドキュメントは SPA + API アーキテクチャシナリオ の一部であり、Angular 2 で SPA を実装する方法を説明します。実装されているソリューションの詳細については、このシナリオを参照してください。 SPA の Angular 2 実装の完全なソースコードは、この GitHub リポジトリで確認できます。

ステップ 1. 設定

アプリケーションには、いくつかの設定情報が必要です。残りの実装に進む前に、各種設定値を含む AuthConfig インターフェースを作成してください。このインターフェースは auth0-variables.ts というファイルに配置します。

ステップ 2. ユーザーを認証する

認証サービスを作成する

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

認証結果を処理する

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

Callback コンポーネントを追加する

Universal Login を使用すると、ユーザーはいったんアプリケーションを離れ、Auth0 がホストするページへ移動します。認証に成功すると、ユーザーはアプリケーションに戻り、そこでクライアント側のセッションが設定されます。 ユーザーの戻り先はアプリケーション内の任意の URL にできますが、認証成功後にユーザーを戻す共通の場所として、専用のコールバックルートを作成することをおすすめします。コールバックルートを 1 つにしておくことには、主に次の 2 つの利点があります。
  • 複数の (場合によっては不明な) コールバック URL を許可リストに追加する必要がなくなります
  • アプリケーションがユーザーのクライアント側セッションを設定している間、読み込み中の表示を出す場所として使えます
CallbackComponent という名前のコンポーネントを作成し、読み込み中の表示を追加します。
この例では、assets ディレクトリに何らかのローディングスピナーが用意されていることを前提としています。実際の動作については、ダウンロード可能なサンプルをご覧ください。 認証後、ユーザーは短時間 /callback ルートに遷移し、その間はローディングインジケーターが表示されます。この間にクライアント側のセッションが設定され、完了後に /home ルートへリダイレクトされます。

ステップ 3. ユーザープロファイルを取得する

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

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

ステップ 4. Scope に基づいて 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 を呼び出すことで行えます。これは、ユーザーが明示的にログインした場合でも、サイレント認証が行われた場合でも、認証フローのたびに実行されます。

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

近年、ブラウザーのユーザープライバシー保護機能の強化により、サードパーティ Cookie へアクセスできなくなり、ユーザー体験に悪影響を及ぼしています。Auth0 では、Refresh Token Rotation の利用を推奨しています。これにより、SPA でリフレッシュトークンを安全に使用できるようになり、ITP のようなブラウザーのプライバシー技術によって UX が損なわれることなく、エンドユーザーはリソースにシームレスにアクセスできます。