在导航到允许取消导航的路线之前,将运行Angular CanActivate保护器。在本教程中,我们将学习什么是CanActivate
防护以及如何使用它来保护路线。我们将构建一个简单的CanActivate
示例应用程序,向您展示如何在实际应用程序中使用它
适用于:角度2,角度4,角度5,角度6,角度7,角度8,角度9。
目录[ 隐藏 ]
什么是CanActivate Guard
Angular CanActivate保护器确定a是否route
可以激活(或渲染组件)。当我们想要检查某些条件时,可以在激活组件或向用户展示之前使用此防护器。这使我们可以取消导航。
CanActivate Guard的用例
检查用户是否已登录
检查用户是否具有权限
此防护的用例之一是检查用户是否已登录到系统。如果用户尚未登录,则防护人员可以将其重定向到登录页面。
如何使用CanActivate Guard
首先,我们需要创建一个Angular Service。
该服务必须导入并实现CanActivate
接口。该接口在@angular/router
模块中定义。接口有一种方法,即canActivate
。我们需要在我们的服务中实施它。CanActivate
接口的详细信息如下所示。
角上最好的书:
前8角最佳书籍,它可以帮助您开始使用角度。
1 2 3 4 5 | interface CanActivate { canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree } |
该方法获取ActivatedRouteSnapshot
&的实例RouterStateSnapshot
。我们可以使用它来访问route参数,query参数等。
Guard必须返回true / false或UrlTree。返回值可以采用可观察或承诺的形式,也可以采用简单boolean
值的形式。
一条路线可以有多个canActivate
警卫。
如果所有警卫都返回true
,则将继续导航至该路线。
如果任何一名守卫返回false
,导航将被取消。
如果任何一名警卫返回a UrlTree
,则当前导航将被取消,并且新的导航将启动到UrlTree
从警卫返回的导航 。
canActivate
保护的例子如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | import { Injectable } from '@angular/core'; import { Router, CanActivate, ActivatedRouteSnapshot,RouterStateSnapshot } from '@angular/router'; @Injectable() export class AuthGuardService implements CanActivate { constructor(private _router:Router ) { } canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean { //check some condition if (someCondition) { alert('You are not allowed to view this page'); //redirect to login/home page etc //return false to cancel the navigation return false; } return true; } } |
canActivate
如下所示,使用防护更新路由定义。您可以在一条路线上应用多个警卫,而一条路线可以有多个警卫
1 2 3 | { path: 'product', component: ProductComponent, canActivate : [AuthGuardService] }, |
CanActivate卫队示例
在示例应用程序中,我们将创建三个组件。在HomeComponent
与ContactComponent
不受保护,并且可以访问的任何用户。用户必须登录系统才能访问ProductComponent
..我们还需要一个LoginComponent
来处理用户登录。
LoginComponent
以下是LoginComponent
与之相关的代码AuthService
login.component.ts
login.component.html
auth.service.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | import { Component, OnInit } from '@angular/core'; import { FormControl, FormGroup } from '@angular/forms'; import { Router, ActivatedRoute } from '@angular/router'; import { AuthService } from './auth.service'; @Component({ templateUrl: './login.component.html', styles: [``] }) export class LoginComponent implements OnInit { invalidCredentialMsg: string; username:string; password:string; retUrl:string="home"; constructor(private authService: AuthService, private router: Router, private activatedRoute:ActivatedRoute) { } ngOnInit() { this.activatedRoute.queryParamMap .subscribe(params => { this.retUrl = params.get('retUrl'); console.log( 'LoginComponent/ngOnInit '+ this.retUrl); }); } onFormSubmit(loginForm) { this.authService.login(loginForm.value.username, loginForm.value.password).subscribe(data => { console.log( 'return to '+ this.retUrl); if (this.retUrl!=null) { this.router.navigate( [this.retUrl]); } else { this.router.navigate( ['home']); } }); } } |
该AuthService
检查是否允许用户登录。它具有login
&logout
用户的方法。我们对该login
方法的实现不进行任何检查。它只是将用户标记为已登录。
产品组件
该ProductComponent
是我们的保护组件。只有登录的用户可以访问它。该组件显示从中获取的产品列表ProductService
。
product.component.ts
product.component.html
product.service.ts
product.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | import { Component, OnInit } from '@angular/core'; import { ProductService } from './product.service'; import { Product } from './Product'; @Component({ templateUrl: "product.component.html", }) export class ProductComponent { products:Product[]; constructor(private productService: ProductService){ } ngOnInit() { this.productService.getProducts() .subscribe(data => { this.products=data; }) } } |
其他成分
app.component.ts
app.component.html
home.component.ts
contact.component.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | import { Component } from '@angular/core'; import { AuthService } from './auth.service'; import { Router } from '@angular/router'; @Component({ selector: 'app-root', templateUrl: './app.component.html' }) export class AppComponent { title = 'Routing Module - Route Guards Demo'; constructor (private authService:AuthService, private router:Router) { } logout() { this.authService.logoutUser(); this.router.navigate(['home']); } } |
可以激活守卫
最后,我们构建了一个CanActivate
防护,它将检查用户是否已登录。如果用户未登录,则将他们重定向到登录页面。
auth-guard.service.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | import { Injectable } from '@angular/core'; import { Router, CanActivate, ActivatedRouteSnapshot,RouterStateSnapshot, UrlTree } from '@angular/router'; import { AuthService } from './auth.service'; @Injectable() export class AuthGuardService implements CanActivate { constructor(private router:Router, private authService: AuthService ) { } canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean|UrlTree { if (!this.authService.isUserLoggedIn()) { alert('You are not allowed to view this page. You are redirected to login Page'); this.router.navigate(["login"],{ queryParams: { retUrl: route.url} }); return false; //var urlTree = this.router.createUrlTree(['login']); //return urlTree; } return true; } } |
首先,我们CanActivate
从@angular/router
模块导入。
该AuthGuardService
工具的CanActivate
界面
AuthServce
在Guard的构造函数中注入
在该CanActivate
方法中,如果用户未登录,我们将重定向用户登录页面。要取消导航,我们必须返回false
或urlTree
如上例所示。
接下来,我们将更新路由定义,并在所有要保护的路由中使用保护功能
app.routes .ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | import { Routes } from '@angular/router'; import { HomeComponent} from './home.component' import { ContactComponent} from './contact.component' import { ProductComponent} from './product.component' import { AuthGuardService } from './auth-guard.service'; import { LoginComponent } from './login.component'; export const appRoutes: Routes = [ { path: 'home', component: HomeComponent }, { path: 'login', component:LoginComponent}, { path: 'contact', component: ContactComponent }, { path: 'product', component: ProductComponent, canActivate : [AuthGuardService] }, { path: '', redirectTo: 'home', pathMatch: 'full' }, ]; |
最后,在中注册服务app.module
。
app.module.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { HttpModule } from '@angular/http'; import { FormsModule } from '@angular/forms'; import { RouterModule } from '@angular/router'; import { AppComponent } from './app.component'; import { HomeComponent} from './home.component' import { ContactComponent} from './contact.component' import { ProductComponent} from './product.component' import { AuthGuardService } from './auth-guard.service'; import { appRoutes } from './app.routes'; import { AuthService } from './auth.service'; import { LoginComponent } from './login.component'; import { ProductService } from './product.service'; @NgModule({ declarations: [ AppComponent,HomeComponent,ContactComponent,ProductComponent,LoginComponent ], imports: [ BrowserModule, FormsModule, HttpModule, RouterModule.forRoot(appRoutes) ], providers: [AuthGuardService,AuthService, ProductService], bootstrap: [AppComponent] }) export class AppModule { } |
运行应用程序。如下图所示,只有登录后才能访问“产品”页面。