ユーザーがログインしていない場合、ログインページに自動的にルーティングしたいと思います。
import { RouterModule, Routes } from '@angular/router';
import { AppComponent } from './app.component';
import { LoginComponent } from './login/login.component';
import { DashBoardComponent} from './dashboard/dashboard.component';
import { NotFoundComponent } from './not-found/not-found.component';
const APPROUTES: Routes = [
{path: 'home', component: AppComponent},
{path: 'login', component: LoginComponent},
{path: 'dashboard', component: DashboardComponent},
{path: '**', component: NotFoundComponent}
];
@NgModule({
declarations: [
AppComponent,
LoginComponent,
DashboardComponent
NotFoundComponent
],
imports: [
BrowserModule,
FormsModule,
HttpModule,
MaterialModule.forRoot(),
RouterModule.forRoot(APPROUTES)
],
providers: [],
bootstrap: [AppComponent]
})
ユーザーがログインしていない場合はLoginComponent
がロードされ、そうでない場合はDashboardComponent
がロードされます。
優先度の低いものからお気に入りまで、あなたが尋ねたことを行う3つの方法を次に示します。
オプション1. AppComponent
でユーザーを強制的にリダイレクトする
@Component({
selector: 'app-root',
template: `...`
})
export class AppComponent {
constructor(authService: AuthService, router: Router) {
if (authService.isLoggedIn()) {
router.navigate(['dashboard']);
}
}
}
あまりよくない。 「ログインが必要」な情報は、それが属するルート宣言に保持する方が良いでしょう。
オプション2. CanActivate
ガードを使用します
ユーザーのログインが必要なすべてのルートにCanActivate
ガードを追加します。
const APPROUTES: Routes = [
{path: 'home', component: AppComponent, canActivate:[LoginActivate]},
{path: 'dashboard', component: DashBoardComponent, canActivate:[LoginActivate]},
{path: 'login', component: LoginComponent},
{path: '**', component: NotFoundComponent}
];
ガードはLoginActivate
と呼ばれます。
それが機能するには、モジュールのproviders
にガードを追加する必要があります。
そして、それを実装する必要があります。この例では、ユーザーがログインしていない場合、ガードを使用してユーザーをリダイレクトします。
@Injectable()
export class LoginActivate implements CanActivate {
constructor(private authService: AuthService, private router: Router) {}
canActivate(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): Observable<boolean>|Promise<boolean>|boolean {
if (!this.authService.isLoggedIn()) {
this.router.navigate(['login']);
}
return true;
}
}
これが意味をなさない場合は、ルートガードに関するドキュメントをご覧ください。 https://angular.io/docs/ts/latest/guide/router.html#guards
このオプションの方が優れていますが、それほど柔軟ではありません。ユーザーのアクセス許可など、「ログイン」以外の条件を確認する必要がある場合はどうなりますか?ロールの名前「admin」、「editor」などのパラメーターをガードに渡す必要がある場合はどうなりますか?
オプション3.ルートdata
プロパティを使用します
私見の最良の解決策は、ルート宣言にいくつかのメタデータを追加して、「このルートではユーザーがログインする必要がある」ことを示すことです。
そのためにroute data
プロパティを使用できます。任意のデータを保持でき、この場合、requiresLogin
またはtrue
のいずれかであるfalse
フラグを含めることを選択しました(フラグが定義されていない場合は、false
がデフォルトになります) :
const APPROUTES: Routes = [
{path: 'home', component: AppComponent, data:{requiresLogin: true}},
{path: 'dashboard', component: DashBoardComponent, data:{requiresLogin: true}}
];
data
プロパティ自体は何もしません。しかし、これを使用して「ログインが必要」なロジックを実施できます。そのためには、もう一度CanActivate
ガードが必要です。
残念です、あなたは言います。次に、保護された各ルートに2つのものを追加する必要があります。メタデータとガード...
しかし:
CanActivate
ガードを最上位のルートにアタッチすると、そのすべての子ルートに対して実行されます[確認される]。そうすれば、ガードを1回使用するだけで済みます。もちろん、保護するルートがすべて親ルートの子である場合にのみ機能します(Rafael Mouraの例には当てはまりません)。data
プロパティにより、あらゆる種類のパラメーターをガードに渡すことができます。特定のロールの名前またはチェックする権限、ユーザーがページにアクセスするために必要なポイントまたはクレジットの数など。これらの発言を考慮して、ガードの名前をAccessGuard
のようなより一般的なものに変更するのが最善です。
ガード内で行うことは実際に状況に依存するため、ガードがルートに接続されたdata
を取得するコードのみを示します。
@Injectable()
export class AccessGuard implements CanActivate {
canActivate(route: ActivatedRouteSnapshot): Observable<boolean>|Promise<boolean>|boolean {
const requiresLogin = route.data.requiresLogin || false;
if (requiresLogin) {
// Check that the user is logged in...
}
}
}
上記のコードを実行するには、次のようなルートが必要です。
{
path: 'home',
component: AppComponent,
data: { requiresLogin: true },
canActivate: [ AccessGuard ]
}
NB。 AccessGuard
をモジュールのproviders
に追加することを忘れないでください。
次のようなこともできます:
{
path: 'home',
component: getHomeComponent(),
data: { requiresLogin: true },
canActivate: [ AccessGuard ]
}
その後:
export function getHomeComponent(): Type<Component> {
if (User.isLoggedIn) {
return <Type<Component>>HomeComponent;
}
else{
return <Type<Component>>LoginComponent;
}
}