发表于: 2019-11-04 22:34:47
1 879
今天完成的事情:
优化angular 任务的 代码(找到2BUG)
理解angualr 响应式表单
了解路由守卫
看完一个小课堂
明天计划的事情:
完成验证在没填完类容,点击按钮不可点击
完一个小课堂理解
看下angular文档其他的命名运用
整理下css常用文件
遇到的问题:
无
收获:
路由守卫
在实际的业务开发过程中,我们经常需要限制某些 URL 的可访问性。比如:对于系统管理界面,只有那些拥有管理员权限的用户才能打开。
我看到过一些简化的处理方案,比如把菜单隐藏起来。但是这样做是不够的,因为用户还可以自己手动在地址栏里面尝试输入,或者更暴力一点,可以通过工具来强行遍历 URL。
请特别注意:前端代码应该默认被看成是不安全的,安全的重头戏应该放在 Server 端,而前端只是做一些基本的防护。
在 Angular 里面,权限控制的任务由“路由守卫”来负责,路由守卫的典型用法:
控制路由能否激活
控制路由的能否退出
控制异步模块能否被加载
控制路由能否激活
代码结构:
auth.guard.ts 里面这样写:
import { Injectable } from '@angular/core';
import { CanLoad, CanActivate, CanActivateChild } from '@angular/router';
import { AuthService } from './auth.service';
@Injectable()
export class AuthGuard implements CanLoad,CanActivate,CanActivateChild{
constructor(private authService:AuthService){
}
/**
* 验证路由是否可以激活
*/
canActivate(){
//在真实的应用里面需要写一个 Service 到后端去验证权限
return this.authService.canActivate();
}
/**
* 验证子路由是否可以激活
*/
canActivateChild(){
//在真实的应用里面需要写一个 Service 到后端去验证权限
return true;
}
}
别忘记把相关的服务放到 app.module.ts 里面去:
providers: [AuthService,AuthGuard]
然后 app.routing.module.ts 里面这样配置:
{
path:'jokes',
data:{preload:true},
canLoad:[AuthGuard],
canActivate:[AuthGuard],
loadChildren: () => import('./jokes/jokes.module').then(m => m.JokesModule)
}
这里的 canActivate 配置项就是用来控制路由是否能被激活的,如果 AuthGuard 里面对应的 canActivate 方法返回 false,jokes 这个路由就无法激活。
在所有子模块的路由里面也可以做类似的配置。
控制路由的退出
有时候,我们还需要控制路由能否退出。
比如:当用户已经在表单里面输入了大量的内容,如果不小心导航到了其它 URL,那么输入的内容就会全部丢失。很显然,这会让用户非常恼火。
所以,我们需要做一定的防护,避免这种意外的情况。
这个例子的运行界面如下:
我们给 jokes 模块单独写了以守卫:
jokes-guard.ts 里面的内容如下:
import { Injectable } from '@angular/core';
import { CanDeactivate } from '@angular/router';
import { JokesComponent } from './jokes.component';
@Injectable()
export class JokesGuard implements CanDeactivate<any>{
canDeactivate(component:JokesComponent){
console.log(component);
if(!component.saved){
return window.confirm("确定不保存吗?");
}
return true;
}
}
注意 jokes.module.ts 和 jokes.routing.module.ts 里面相关的配置。
控制模块能否被加载
除了可以控制路由能否被激活之外,还可以控制模块能否被加载,处理方式类似,在 AuthGuard 里面增加一个处理方法:
/**
* 验证是否有权限加载一个异步模块
*/
canLoad(){
//在真实的应用里面需要写一个 Service 到后端去验证权限
return this.authService.canLoad();
}
如果 canLoad 方法返回 false,模块就根本不会被加载到浏览器里面了。
评论