今回は、Angularを使用した認証関連の画面制御について検証してみました。
以前は、@angular/routerモジュールのCanActivateを使って制御していましたが、最新のAngularバージョンでは非推奨となり、CanActivateFnの利用を推奨するようになったようです。
実装したこと
- @angular/routerのCanActivateからCanActivateFnへのポーティング
- エンドポイントAPIとの通信
- Webストレージに情報を格納/消去
ソースコード
今回動作検証した際に使用したソースコードはこちらに公開しています。
何かの参考にしていただけると幸いです。
主なモジュール
- Angular ver16
- Ionic/Angular Ver7
- rxjs Ver7
- その他エンドポイントexpress.jsなど
Auth GuardとCanActivateFn
Auth Guard自体の考え方は、多くの諸先輩方が他のページで紹介くださっていますので、当投稿では割愛させていただきます。
auth guardを実装するにあたり、CanActivate(Ver15)からCanActivateFn(Ver16)変更になった点に焦点をあてて紹介したいと思います。
以前のバージョンでは
以前までのIonic/Angularでは、ページを追加する際のコマンドにguardsという選択肢があり、大変便利に自動生成してくれていました。自動生成された結果、CanActivateが適用されて基本的なコードが展開されます。
ionic generateを使用して追加する例:
$ ionic g
? What would you like to generate?
module
class
directive
> guard
pipe
interface
enum
(Move up and down to reveal more choices
? Name/path of guard: protected
> ng.cmd generate guard auth --project=app
? Which type of guard would you like to create? (Press <space> to select, <a> to toggle all, <i> to invert selection, and <enter> to proceed)
>(*) CanActivate
( ) CanActivateChild
( ) CanDeactivate
( ) CanLoad
( ) CanMatch
CREATE src/app/protected.guard.spec.ts (331 bytes)
CREATE src/app/protected.guard.ts (457 bytes)
[OK] Generated guard!
指定したパスに「protected.guard.ts」が生成されます。
自動生成された例:
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, CanActivate, RouterStateSnapshot, UrlTree } from '@angular/router';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class ProtectedGuard implements CanActivate {
canActivate(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
// ここで判定結果を返却する実装が一般的です。
// 外部サービス呼び出しや内部のチェックロジックを実装するなど。
return true;
}
}
今回は
冒頭で申しました通り、最新のAnbular16を使用する場合は、CanActivateではなくCanActivateFnを使用するように変更します。
protected.guard.ts
上記から以下のように実装を変更します。
export const protectedGuard: CanActivateFn
を新規で追加します。
export const protectedGuard: CanActivateFn = (_route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => {
const guard = inject(ProtectedGuard);
return guard.canActivate(state);
};
export class ProtectedGuard {
canActivate(state: RouterStateSnapshot): Observable<boolean> {
// 認証状態を判定するロジックを入れる
return true;
}
}
app-routing.module.ts
なお、Routerの設定は古いバージョンから特に意識することなく同様の実装ができます。
canActivate: [ProtectedGuard]
の部分は以前までのバージョンと同様の記述です。
path: 'dashboard',
loadChildren: () => import('./pages/dashboard/dashboard.module').then( m => m.DashboardPageModule),
canActivate: [ProtectedGuard]
次回は
現在FireFlyの検証をすすめるなかで今後フロントエンドの認証関連のアプリが必要になるだろうということで、認証部分の仕組みにて実装してみました。
次回は、FireFlyをベースにしたアプリを製造する際に必要となる技術要素について検証を進めたいと思います。