【问题标题】:Angular2 router canActivate after logoutAngular2路由器可以在注销后激活
【发布时间】:2016-11-02 13:05:59
【问题描述】:

我在某些路由中使用了登录保护(例如“/profile”)。看起来像这样:

canActivate() {
    if (this.user.islogin) return true;
    this.router.navigate(['']);
}

如果用户未登录,它会将用户重定向到主页并尝试访问某些路由。它工作正常。 用户可以从任何页面注销。我希望我的应用程序具有下一个行为: 如果用户在“/profile”页面并单击“注销”,则应通过 canActivate() 方法将他重定向到主页。但是在这种情况下不会调用此方法。我应该怎么做才能运行 canActivate()(重新加载页面,手动调用)? 我的注销方法:

logout() {
    localStorage.removeItem('auth_token');
    this.islogin = false;
}

我尝试在注销方法中添加this.router.navigate([this.router.url]);,但结果是一样的。 只有当我重新加载页面时,angular2 才会重定向我。 什么是正确的方法?

【问题讨论】:

    标签: angular


    【解决方案1】:

    问题是旧的,但问题是最新的。

    从 Angular v6 开始,您可以设置路由器的 onSameUrlNavigation 属性:

    RouterModule.forRoot(routes, {
        ...
        onSameUrlNavigation: 'reload'
    })
    

    并设置runGuardsAndResolvers 你需要什么:

    {
        path: '',
        component: AccountComponent,
        canActivate: [AuthGuard],
        runGuardsAndResolvers: 'always'
    }
    

    在您的注销方法中,只需调用相同的路由,您的身份验证守卫的canActivate 方法就会被触发:

    signout(): void {
        this.store.dispatch({
            type: AuthActionTypes.Signout
        });
        // Navigate to the same url to invoke canActivate method
        // in routes with runGuardsAndResolvers.
        // Also activated onSameUrlNavigation router property.
        this.router.navigate([this.auth.redirectUrl]);
    }
    

    在上面的示例中,redirectUrl 是保存当前 url 的属性。

    【讨论】:

    • 我以前不知道runGuardsAndResolvers: 'always'
    【解决方案2】:

    考虑到您的守卫只使用islogin,并且您在用户注销时将其设置为 false,最简单的方法是在注销时简单地重定向:

    logout() {
        localStorage.removeItem('auth_token');
        this.islogin = false;
        this.router.navigate(['']);    <---- ADD THIS
    }
    

    如果你想重用canActivate()中的逻辑而不先改变路由,你可以这样做:

    首先,在您的 logout() 所在的任何位置注入服务:

    constructor(
        private router: Router,
        private route: ActivatedRoute,
        private canActivateGuard: CanActivateGuard) {}
    

    (只需使用您使用的名称而不是CanActivateGuard

    接下来,拨打logout()

    logout() {
        this.canActivateGuard.canActivate(
            this.route.snapshot,
            this.router.routerState.snapshot);
    }
    

    【讨论】:

    • 这样的问题是,如果您在不需要该保护的路由上注销,它将运行,这是错误的
    • 2年后再看这个,我认为robimsim74的答案是正确的。
    • 检测到循环依赖
    【解决方案3】:

    虽然一个老问题我遇到了类似的问题,但我只是通过使用 async 和 await

    解决了它

    我正在使用 Firebase 身份验证Angular,使用 AngularFireAuth

    当我使用以下代码时:

      logout(){
        this.fbAuthService.fbSignOut();
        this.router.navigate(['/login']);
      }
    

    用户已正确退出,但 this.router.navigate(['/login']) 不起作用!如果我重新加载页面,它会起作用。

    后来我怀疑我可能必须等待完成注销过程然后调用this.router.navigate(['/login'])) 函数。

    所以我把它改成了:

      async logout(){
        await this.fbAuthService.fbSignOut();
        this.router.navigate(['/login']);
      }
    

    它就像一个魅力!希望它对可能偶然发现此问题的人有所帮助。

    【讨论】:

      猜你喜欢
      • 2016-12-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-15
      • 2018-11-22
      • 1970-01-01
      • 1970-01-01
      • 2014-02-11
      相关资源
      最近更新 更多