1. 前言
一个网站,通常都会包含公开页面和受保护页面两种,如果是 OA 或者企业应用网站,甚至可能全部都是保护页面,访问者需要在进行身份认证后,才能正常的浏览相关页面。
在本实验中, 我们会创建一个登录页面, 一个受保护的页面, 和一个面向公众公开的信息页面. 当用户访问受保护页面时, 需要先登录再访问, 而公众公开页面不需要登录即可访问.
2. 创建一个 angular 应用
创建一个名为 test 的新 angular 项目
执行完以上命令, angular cli 将为我们创建基本的项目骨架.
对于项目的结构的详解, 可以参考鹏叔的博客空间关于创建 Angular 项目
3. 创建页面
创建三个页面, 一个命名为 public, 一个为 private, 一个为 login, public 页面无需登录即可访问, 而 private 页面需要先登录然后才能访问,
当用户在未登录的情况下访问 private, 则被导航到 login 页面被要求登录.
创建 public page, anuglar 的每一个页面都对于于一个 component, 所以创建页面也就是创建 component
1 2 3 4 5 6
| $ ng g component components/public CREATE src/app/components/public/public.component.html (21 bytes) CREATE src/app/components/public/public.component.spec.ts (626 bytes) CREATE src/app/components/public/public.component.ts (275 bytes) CREATE src/app/components/public/public.component.css (0 bytes) UPDATE src/app/app.module.ts (407 bytes)
|
创建 private page
1 2 3 4 5 6 7 8
| $ ng g component components/private CREATE src/app/components/private/private.component.html (22 bytes) CREATE src/app/components/private/private.component.spec.ts (633 bytes) CREATE src/app/components/private/private.component.ts (279 bytes) CREATE src/app/components/private/private.component.css (0 bytes) UPDATE src/app/app.module.ts (504 bytes)
|
创建 login page
1 2 3 4 5 6
| $ ng g component components/login CREATE src/app/components/login/login.component.html (20 bytes) CREATE src/app/components/login/login.component.spec.ts (619 bytes) CREATE src/app/components/login/login.component.ts (271 bytes) CREATE src/app/components/login/login.component.css (0 bytes) UPDATE src/app/app.module.ts (835 bytes)
|
4. 添加路由
4.1. 引入@angular/router 包
1
| npm i --save @angular/router
|
4.2. 创建路由配置
前面提到每一个页面都会对应一个 component, 当用户访问 angular SPA 应用时, 当路径匹配到路由中配置的路径时, 就会将该路径对应的 component 加载到根组件 AppComponent 的<router-outlet></router-outlet>
节点.
在 src/app 目录下创建一个名为 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 { PublicComponent } from "./components/public/public.component"; import { PrivateComponent } from "./components/private/private.component"; import { LoginComponent } from "./components/login/login.component";
export const rootRouterConfig: Routes = [ { path: "login", component: LoginComponent, }, { path: "public", component: PublicComponent, }, { path: "private", component: PrivateComponent, }, ];
|
4.3. 加载路由配置
并在 app.module.ts 中引入该模块.
根路由模块包含了路由所需的使用服务,它以路由配置为参数,调用 RouterModule.forRoot()
app.module.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| import { rootRouterConfig } from "./app.routes";
import { RouterModule } from "@angular/router";
const rootRouterModule: ModuleWithProviders = RouterModule.forRoot(rootRouterConfig);
@NgModule({ declarations: [], imports: [rootRouterModule], providers: [], bootstrap: [AppComponent], }) export class AppModule {}
|
修改根组件
一般情况下,这个指令是放在根组件中。
app.conponent.html
1 2 3
| <section class="container"> <router-outlet></router-outlet> </section>
|
5. 路由进阶 - 身份认证
首先我们添加一个 AuthGuard, 此 Guard 的职责就是坚持用户是否登录, 如果未登录则将用户导航到登陆页面.
然后实现 canActivate 接口
src\app\guards\auth.guard.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 43 44
| import { Injectable } from "@angular/core"; import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot, UrlTree, } from "@angular/router"; import { Observable } from "rxjs";
@Injectable({ providedIn: "root", }) export class AuthGuard implements CanActivate { constructor(private router: Router) {}
canActivate( route: ActivatedRouteSnapshot, state: RouterStateSnapshot ): | Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree { console.log("AuthGuard#canActivate called"); if (this.isLoggedIn()) { console.log("AuthGuard: 用户已登陆。"); return true; } this.router.navigate(["/login"], { queryParams: { returnUrl: state.url } }); return false; }
private isLoggedIn(): boolean { let loggedIn: boolean = false; if (!loggedIn) { console.log("AuthGuard: 用户未登陆。"); } return loggedIn; } }
|
这样一个简单的 AuthGuard 就实现了, 在这个身份验证 guard 中, 我们强制的将 loggedIn 状态设置为 false, 让用户处于未登录状态, 来模拟用户未登录状态先, 访问 private 页面被导航到登录页面.
有了 AuthGuard 后, 我们修改一下路由配置, 让其守护 private 页面, 保证只有登录用户才让访问 private 页面.
修改 app.routes.ts
1 2 3 4 5
| { path: 'private', component: PrivateComponent, canActivate: [AuthGuard] },
|
同时修改一下 app.module.ts, 在 application 启动时加载 AuthGuard
6. Angular 系列文章
最新更新以及更多 Angular 相关文章请访问 Angular 合集 | 鹏叔的技术博客
7. 参考文档
Angular 2.0 SPA 应用 - 身份认证 2
Angular2 使用 Guard 和 Resolve 进行验证和权限控制