ユーザーがブラウザーのタブでルートを手動で変更してEnterキーを押すと発生する問題で立ち往生しています。これにより、ユーザーが入力した状態にui-router/angular2-routerが強制的にナビゲートされます。これを防ぎ、自分のWebサイトのボタンクリックで実装したフローを介したルーティングのみを許可します。
その2018! Angular 5がここにあり、これがこの問題の解決策です。BAMMそのCanActivateルートがアクティブ化できるかどうかを決定するガードとしてクラスが実装できるインターフェイス。
この機能を追加して、定義した条件に基づいて一部のルートへのアクセスを禁止できます。 CanActivateインターフェイスを実装し、canActivateメソッドを定義するAuthGuardなどのサービスをルート構成に追加できます。
class Permissions {
canGoToRoute(user: UserToken, id: string): boolean {
return true;
}
}
@Injectable()
class AuthGuard implements CanActivate {
constructor(private permissions: Permissions, private currentUser: UserToken) {}
canActivate(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): Observable<boolean>|Promise<boolean>|boolean {
return this.permissions.canGoToRoute(this.currentUser, route.params.id);
}
}
アクセスをある条件から保護したいルートがある場合は、次のようにガードを追加します。
const appRoutes: Routes = [
{ path: 'crisis-center', component: CrisisListComponent },
{
path: 'heroes',
canActivate: [AuthGuard],
component: HeroListComponent,
data: { title: 'Heroes List' }
},
{ path: '',
redirectTo: '/heroes',
pathMatch: 'full'
},
{ path: '**', component: PageNotFoundComponent }
];
ここで、ルートheroes
とそのすべての子には、その上にガード層があります。したがって、AuthGuardサービスによって返されるブール値に基づいて、ユーザーはこのルートへのアクセスを許可または拒否されます。
ガードのコンストラクターにルーターをインポートできます。このルーターインスタンスには現在のURLが含まれます。 canActivateのActivatedRouteSnapshotおよびRouterStateSnapshotには、ユーザーがアクセスしようとしているURLが含まれます。
以下の例では、ユーザーが外部ページからルートに直接アクセスできないようにしています。
import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from '@angular/router';
import { Observable } from 'rxjs/Observable';
@Injectable()
export class DirectAccessGuard implements CanActivate {
constructor(private router: Router) {}
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
// If the previous URL was blank, then the user is directly accessing this page
if (this.router.url === '/') {
this.router.navigate(['']); // Navigate away to some other page
return false;
}
return true;
}
}
このガードをルーティングモジュールに追加します
{ path: 'signup/:type/:step', component: SignupComponent, canActivate: [DirectAccessGuard] }
$stateChangeStart
イベントはこれを処理する適切な場所です。このイベントは、URL
に移動しようとすると発生します。その時点で、ユーザーが認証されているかどうかを確認でき、認証されていない場合は、バウンスしてログインし直します。
あなたはこのようなイベントをフックします:
angular
.module('myApp')
.run(function ($rootScope, $state, authFactory) {
$rootScope.$on('$stateChangeStart', function () {
//if user is not logged in
if(!authFactory.isAuthed()){
$state.go('login')
}
})
});
それが役に立てば幸い。