Angular 8 身份验证防护 - 确定用户是来自外部还是来自应用内部



似乎是一个愚蠢的问题,但由于某种原因我无法弄清楚答案。

我有一个身份验证保护,它检查存储在本地存储中的 JWT 令牌的过期时间,并抛出"您的会话已过期"对话框,该对话框将用户重定向到 On Close 登录。

在当前状态下,仅当浏览器在存储中具有此令牌时,才会引发对话框;否则它会直接重定向到登录页面。

canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): boolean {
if (!this._auth.isAuthenticated()) {
if (this._auth.hasToken()) {
this._dialogService.openErrorDialog('Your session has expired, please re-login', 0)
.afterClosed()
.subscribe(() => this.navigateToLogin(state.url));
} else {
this.navigateToLogin(state.url);
}
return false;
}
return true;
}

我想实现以下逻辑:当用户浏览某个应用程序页面时令牌过期 ->用户导航到另一个页面 - 抛出>对话框 ->重定向到登录; 但是,如果用户从外部导航到应用程序中的某个页面,它应该直接重定向他登录页面,而不会抛出对话框,即使浏览器本地存储中已经有过期的令牌。

我试图基于此破解一些解决方案,但没有成功 - 虽然我可以从 canActivate 函数返回Observable<boolean>,但我无法弄清楚如何使 rxjsmap处理pairwise的结果 - 所以我可以使用存在以前的 URL 的事实来确定用户来自哪里。

任何帮助非常感谢。

为您创建了堆栈闪电战示例。使用了您在链接中共享的信息并创建了如下所示的服务。

@Injectable({ providedIn: "root" })
export class FirstVisitService {
readonly isFirstVisit = new BehaviorSubject<boolean>(true);
constructor(router: Router) {
router.events
.pipe(
filter(event => event instanceof NavigationEnd),
first()
)
.subscribe((e: NavigationEnd) => {
this.isFirstVisit.next(false);
this.isFirstVisit.complete();
});
}
}

并将其注入 auth.guard 并像这样使用:

constructor(private service: FirstVisitService   ) { }
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): Observable<boolean> | Promise<boolean> | boolean {
if (this.service.isFirstVisit.value) {
console.log("first time");
}  else{
console.log("not first time");
}
return true;
}

您必须在应用程序模块中导入它

export class AppModule {
constructor(f : FirstVisitService) {}
}

因此,它会在任何事件发生之前发生并订阅路由器事件。

只需在src/app/app.components.ts中设置重定向即可。
这个"组件"是 AppModule 被提升后的第一个被提升的组件。
因此,只需将行放在那里,当用户来自外部时,它将始终重定向。


// src/app/app.components.ts
import { Component } from '@angular/core';
import { Router } from '@angular/router';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'],
})
export class AppComponent {
constructor(private router: Router) {
// no matter where the user is going
// just redirect to login!
// this will only run the first time the app bootstraps
this.router.navigateByUrl('/login'); // <--------
}
}

最新更新