angular - Angular Routing 演示:如果注销则自动远离保护区(重新启动 canActivate 守卫)
问题描述
请参阅有关路由的官方 Angular 文档:https ://angular.io/guide/router
及其演示:https ://stackblitz.com/angular/pbqlrdpbpvx
该演示演示了一个管理部分,只有在 auth 服务状态isloggedIn
返回 true 时才能访问该部分。该部分受 canActivate auth-guard 保护。
从本质上讲,canActivate 守卫只会在您尝试访问页面时触发一次。如果您的身份验证服务状态ìsloggedIn
返回 false,则正确地将您路由到登录过程。
但是,如果我的身份验证服务状态的值发生变化,我需要我的 canActivate 警卫每次触发ìsloggedIn
,以确保如果身份验证状态本身变为假(即,如果我稍后使用到期日期或其他内容),以让用户自动离开受保护的部分。如果值突然变为 false,他将不会留在保护区页面上。
通过在顶部导航中添加一个简单的注销按钮来重现的步骤:
- 扩展演示(https://stackblitz.com/angular/pbqlrdpbpvx),顶部有注销按钮:
app.component.ts:
import { Component } from '@angular/core';
import { RouterOutlet } from '@angular/router';
import { slideInAnimation } from './animations';
import { AuthService } from './auth/auth.service';
@Component({
selector: 'app-root',
templateUrl: 'app.component.html',
styleUrls: ['app.component.css'],
animations: [ slideInAnimation ]
})
export class AppComponent {
constructor(public authService: AuthService) {}
getAnimationData(outlet: RouterOutlet) {
return outlet && outlet.activatedRouteData && outlet.activatedRouteData['animation'];
}
logout() {
this.authService.logout();
}
}
app.component.html:
<h1 class="title">Angular Router</h1>
<nav>
<a routerLink="/crisis-center" routerLinkActive="active">Crisis Center</a>
<a routerLink="/superheroes" routerLinkActive="active">Heroes</a>
<a routerLink="/admin" routerLinkActive="active">Admin</a>
<a routerLink="/login" routerLinkActive="active">Login</a>
<a (click)="logout()" *ngIf="authService.isLoggedIn">Click To Logout</a>
<a [routerLink]="[{ outlets: { popup: ['compose'] } }]">Contact</a>
</nav>
<div [@routeAnimation]="getAnimationData(routerOutlet)">
<router-outlet #routerOutlet="outlet"></router-outlet>
</div>
<router-outlet name="popup"></router-outlet>
单击登录按钮并登录-您将被路由到管理部分,顶部导航上的注销按钮将显示。
单击注销按钮,查看视图保持不变。您仍在管理部分。
预期行为:
如果 auth 服务的 isLoggedIn 状态变为 false,用户将自动被重定向到登录页面。因此, anActivate 守卫应该在值更改时自动触发。
当前行为的原因:
auth guard 的 canActivate 决定你是否可以访问页面,当你进入页面时,它只在开始时检查一次。
当前解决方案:
通过对登录部分的路由调用扩展注销按钮的单击功能。然而,这并不涵盖所有用例。
提前致谢。
解决方案
您是否尝试过从 Auth Guard 调用 Observable,
constructor(private authService:AuthService, private router:Router) { }
canActivate(next:ActivatedRouteSnapshot, state:RouterStateSnapshot) {
return this.authService.isLoggedIn().map( v => {
if (v) {
return true;
}
}).catch(() => {
this.router.navigate(['/login']);
return Observable.of(false);
});
}
推荐阅读
- java - Android Studio,javax.net.ssl.SSLHandshakeException:不可接受的证书
- javascript - 弹跳球在碰撞时错过了一些平台
- python - 如何计算字母组合的出现次数?
- c# - OData 是否允许用户使用 IQueryable 查询 SQL EF 数据库?
- javascript - 如何实现滑动监听器?
- reactjs - 找不到所需的“intl”对象。
需要存在于组件祖先中 - c++ - 为什么一个方法对同一个变量有 const 和非 const 参数?
- docker - 我们可以使用 curl 命令将 docker 映像推/拉到 nexus 3 存储库吗
- c# - 如何以编程方式单击图钉?
- javascript - 如何从单独的 js 文件中调用角度 $scope 函数?