LoginSignup
13
14

More than 3 years have passed since last update.

Angular+Cognitoのユーザー認証にGuardを使う

Last updated at Posted at 2017-11-03

はじめに

以前、Angular+Cognitoのユーザー認証付きSPAのサンプルという記事を書きましたが、このときは各コンポーネントでCognito認証済かどうかのチェックをのチェックを行っていましたが、AngluarにはGuardというルーティングを行うタイミングで、ルーティングの拒否、許可の分岐を行える仕組みがあります。
今回は、前回作成したサンプルをGuardを使った形に書き換えていきたいと思います。

手順

guardの作成

angluar-cliにはguardを作成するgenerateコマンドも要されているので、簡単にひな形を作成することが出来ました。

$ ng g guard guard/auth
auth.guard.ts
import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { Observable } from 'rxjs/Observable';

@Injectable()
export class AuthGuard implements CanActivate {
  canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
    return true;
  }
}

また、サービスを追加するときと同様にapp.module.tsにインポートし、@NgModuleprovidersに追加しておきます。

guardの修正

前回の記事でcognito.service.tsに実装したisAuthenticated ()メソッドを使ってguard内で認証済み判定を行います。
angluar-cliで作成されたguardを見て分かる通り、canActivateはObservable、Promiseそれぞれのbooleanまたはbooleanを戻り値に取ることが出来ます。

auth.guard.ts
import { Injectable } from '@angular/core';
import { CanActivate, Router, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import { CognitoService } from './../service/cognito.service';

@Injectable()
export class AuthGuard implements CanActivate {

  constructor(
    private cognitoService: CognitoService,
    private router: Router
  ) {

  }
  canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Promise<boolean> {
      return this.cognitoService.isAuthenticated()
      .then(data => {
        return Promise.resolve(true);
      }).catch(err => {
        this.router.navigate(['/login']);
        return Promise.resolve(false);
      });
    }
}

上記では、CognitoServiceとRouterをインポートしています。
Routerをインポートするのは、認証済み出なかった場合に、loginページにリダイレクトするためです。

Routerの設定

app-routing.module.tsを修正して、RouterでGuardを使用するように設定します。
認証が必要な、routes内のuploaduploadオブジェクトにcanActivateパラメータを追加して先ほど作成したGuardを指定します。

app-routing.module.ts
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { SignupComponent } from './public/signup/signup.component';
import { LoginComponent } from './public/login/login.component';
import { UploadComponent } from './secure/upload/upload.component';
import { FilesComponent } from './pages/files/files.component';
import { AuthGuard } from './guard/auth.guard';

const routes: Routes = [
  {
    path: 'signup',
    component: SignupComponent,
  },
  {
    path: 'login',
    component: LoginComponent,
  },
  {
    path: 'upload',
    component: UploadComponent,
    canActivate: [AuthGuard]
  },
  {
    path: 'files',
    component: FilesComponent,
    canActivate: [AuthGuard]
  },
  {
    path: '',
    redirectTo: '/upload',
    pathMatch: 'full'
  }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

コンポーネントの修正

上記までの手順でguardの設定が済んだので、各コンポーネントのコンストラクタ内で行っている認証チェックのロジックを削除してしまいます。
files.component.tsupload.component.tsそれぞれの以下の箇所を削除します。

files.component.ts
-    this.cognito.isAuthenticated()
-    .then(res => console.log(res))
-    .catch((err) => {
-      return console.log(err) || this.router.navigate(['/login']);
-    });

手順としては以上です。
開発サーバーを立ち上げて、それぞれのページにアクセスすると正しくルーティングされているのが確認できるかと思います。

今回のサンプルコード

参考

angular.io
https://angular.io/guide/router

Auth0 + AngluarのGuardを使った例ですが、大変参考になりました🙏
https://qiita.com/ovrmrw/items/f7003a5df4aa58cb4857

13
14
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
14