由于Observers在Angular中的深度以及调试那种事情所涉及的困难,我可能会对这里发生的事情略微偏离,但这正是我所观察到的 .
我有一个使用@ angular / router 5.2.6的Angular 5应用程序,我有一个Guard服务,我有一个外部SSO类型的用户身份验证服务 . 如果用户未经过身份验证,我需要能够重定向到我的身份验证服务,如果需要,请登录,然后返回他们最初尝试获取的SAME URL .
所以我有路由设置并将我的Guard服务作为路由的canActivate条件 . 我用
window.location.href = "...";
从我的应用程序重定向到auth服务 . 并且在设置重定向后也从canActivate方法返回false .
我的身份验证服务依赖于Referrer标头,以了解在用户通过身份验证后将用户返回的位置 . 这在大多数浏览器中都可以正常工作,但在Chrome中,似乎浏览器会在执行重定向之前让整个事件堆栈展开 .
这就是说似乎发生的事情是:
-
window.location.href = "...";
-
canActivate返回false .
-
由于路由无法激活,因此用户将被删除到应用程序根目录 .
-
一瞬间,重定向发生 .
但是因为我们登陆了应用程序根FIRST,所以Referrer标头错误 .
那么我的选择是什么?
-
如果我返回true而不是false,重定向确实会发生正确的 Headers ,但这不是最安全的事情 .
-
如果我将查询参数与原始URL一起使用,我需要在我的应用程序和auth服务之间 Build 一个中介,将其转换回Referrer标头 .
-
我可以使用auth服务URL创建一个Anchor标记,并以编程方式单击它,而不是窗口位置 . 这似乎会使路由器短路并阻止canActivate完全展开 .
我还可以做些什么?也许某种Observable返回等待popstate或hashchange并强制返回URL?有没有我看不到的东西,你认为我的问题是否正确?
编辑:添加canActivate方法
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
const url: string = state.url;
if (this.authService.config.permissionsEndpointUrl && this.authService.config.hasUserPermissions) {
// If permissions are configured, check both the user session token and user access permissions
return this.checkLogin(url) && this.checkPermissions(route.data['permissions']);
} else {
// Otherwise, only check the user session token
return this.checkLogin(url);
}
}
private checkLogin(url: string): boolean {
const currentUser = this.authService.getUserSessionDetails();
if (currentUser && currentUser.token && this.authService.tokenNotExpired(currentUser.token)) {
return true;
}
// Store the attempted URL for redirecting after login
this.authService.redirectUrl = url;
this.authService.redirectToLogin(true);
return false;
}
redirectToLogin(guardMode: boolean = false): void {
...
if (this.config.loginRoutePath) {
window.location.href = this.config.loginRoutePath;
}
...
}