序章

Angularルーターのナビゲーションガードを使用すると、ナビゲーションの特定の部分へのアクセスを許可または削除できます。 もう1つのルートガードであるCanDeactivateガードを使用すると、ユーザーが誤って変更を保存せずにコンポーネントを離れるのを防ぐこともできます。

注:このようなクライアント側のルートガードは、セキュリティ機能を目的としたものではありません。 彼らは賢いユーザーが保護されたルートに到達する方法を考え出すのを妨げることはありません。 このようなセキュリティはサーバーに実装する必要があります。 代わりに、アプリのユーザーエクスペリエンス(UX)を向上させる方法として意図されています。

使用可能なルーティングガードの4つのタイプは次のとおりです。

  • CanActivate:ルートをアクティブ化できるかどうかを制御します。
  • CanActivateChild:ルートの子をアクティブ化できるかどうかを制御します。
  • CanLoad:ルートをロードできるかどうかを制御します。 これは、遅延ロードされる機能モジュールで役立ちます。 ガードがfalseを返した場合でも、ロードされません。
  • CanDeactivate:ユーザーがルートを離れることができるかどうかを制御します。 このガードは、ユーザーがブラウザタブを閉じたり、別のアドレスに移動したりすることを妨げるものではないことに注意してください。 アプリケーション自体からのアクションを防ぐだけです。

CanActivateルートガードの使用

ルートガードは、ほとんどの場合、必要なルートガードインターフェイスを実装するクラスとして実装されます。

CanActivateルートガードの例を考えてみましょう。ここでは、ユーザーが認証されているかどうかをauthサービスに要求します。

can-activate-route.guard.ts
import { Injectable } from '@angular/core';
import {
  CanActivate,
  ActivatedRouteSnapshot,
  RouterStateSnapshot 
} from '@angular/router';
import { AuthService } from './auth.service';

@Injectable()
export class CanActivateRouteGuard implements CanActivate {
  constructor(private auth: AuthService) {}

canActivateメソッドを宣言することにより、CanActivateインターフェイスを実装する方法に注目してください。 現在のルートに関する情報が必要な場合は、オプションでActivatedRouteSnapshotRouterStateSnapshotにアクセスできます。

この例では、canActivateは、ユーザーが認証されているかどうかに応じてブール値を返しますが、ブール値に解決されるobservableまたはpromiseも返す可能性があります。

それらを使用するには、ルートガードをサービスのように提供する必要があります。

それをアプリモジュールのプロバイダーに追加しましょう。

app.module.ts
// ...
import { AppRoutingModule } from './app-routing.module';
import { CanActivateRouteGuard } from './can-activate-route.guard';

import { AuthService } from './auth.service';

そして最後に、ルーティング構成の一部としてガードを追加する必要があります。

ルーティングモジュールの例を次に示します。

app-routing.module.ts
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

import { HomeComponent } from './home.component';
import { DashboardComponent } from './dashboard.component';
import { CanActivateRouteGuard } from './can-activate-route.guard';

const routes: Routes = [
  { path: '', component: HomeComponent },
  { path: 'dashboard',
    component: DashboardComponent,
    canActivate: [CanActivateRouteGuard]
  }
];

これで、認証されたユーザーのみが/dashboardルートをアクティブ化できます。

ルート定義にガードの配列を提供する方法に注目してください。 つまり、1つのルートに複数のガードを指定でき、指定された順序で評価されます。

CanLoadCanActivateChildの実装も同様の方法で実行されます。

注: CanLoadインターフェースは、現在のルーターの状態またはアクティブ化されたルートへのアクセスがそれほど多くありません。

これで、CanActivateルートガードの例は終わりです。

CanDeactivateルートガードの使用

CanDeactivateガードは、非アクティブ化するコンポーネントを提供する必要があるという点で、実装にわずかな違いがあります。 これにより、問題のコンポーネントを調べて、保存されていない変更のようなものがあるかどうかを確認できます。

CanDeactivateルートガードの例を考えてみましょう。

can-deactivate-route.guard.ts
import { Injectable } from '@angular/core';
import { CanDeactivate } from '@angular/router';

import { DashboardComponent } from './dashboard.component';

上記の例では、ダッシュボードコンポーネントクラスにunsavedChangesというメンバーがあり、未保存の変更があると常にtrueになると想定しています。 保存されていない変更がないか、ユーザーが確認しない限り、ルートは非アクティブ化されません。

これで、CanDeactivateルートガードの例は終わりです。

結論

このチュートリアルでは、CanActivateCanDeactivateのようなAngularのルートガードについて学びました。

Angularについて詳しく知りたい場合は、Angularトピックページで演習とプログラミングプロジェクトを確認してください。