【问题标题】:Angular2 : Redirect to another route conditionally when logoutAngular2:注销时有条件地重定向到另一条路线
【发布时间】:2016-12-17 08:27:53
【问题描述】:

我在 Angular2 和路由器的特定用例上有点挣扎。

假设我们有 3 条路线。主页、列表和个人资料。

“配置文件”是一个受保护的路由:用户必须经过身份验证才能访问此路由。

如果用户在“个人资料”页面并退出,我希望能够检测到他不再被允许在当前页面上,并将他重定向到“主页”页面。

但是,如果他在“列表”页面并退出,我不想做任何事情(用户可以留在这里,因为它不是受保护的路线)。

假设我有很多路线并且我想避免在每个组件中放置这种“用户允许”逻辑,有人知道我该如何实现吗?

【问题讨论】:

    标签: angular redirect router guard


    【解决方案1】:

    总结

    在我的情况下,我喜欢通过检查我保存到本地存储的令牌的验证来让我的用户访问受保护的路由。因此,如果我将它们注销,我会删除令牌以及我当前在本地存储中拥有的任何数据。您可以在每条路线中使用此功能。

      public logout() {
        localStorage.removeItem('profile');
        localStorage.removeItem('access_token');
        this.userProfile = undefined;
        this.router.navigateByUrl('/home');
      };
    

    我创建了一个身份验证服务。您可以创建两个不同的服务或两个不同的功能。真的,你有很多选择。这是一种选择。

    解决方案

    要注销并重定向,

      public logout() {
        localStorage.removeItem('profile');
        localStorage.removeItem('access_token');
        this.userProfile = undefined;
        this.router.navigateByUrl('/home');
      };
    

    您可以在每个组件中使用此功能。或页面。如果用户在个人资料页面上,则基本上重定向路线。但如果用户不在需要重定向的页面或路线上,则删除

    this.router.navigateByUrl('/home');
    

    来自函数,因此用户不会被重定向。

    所以你可以有两个服务

        public.service.ts
        @Injectable()
    export class Public {
         public logout() {
            localStorage.removeItem('profile');
            localStorage.removeItem('access_token');
            this.userProfile = undefined;
          };
    

    然后在您想要注销用户但将他们留在同一页面上的页面中使用此服务

    export class SomeComponent {
           constructor( private router: Router, private public: Public  ) { }
    }
    

    所以当使用注销功能时,它不会重定向。

    然后在用户注销时重定向,像这样添加这个服务,

           secure.service.ts
        @Injectable()
    export class Secure {
         public logout() {
            localStorage.removeItem('profile');
            localStorage.removeItem('access_token');
            this.userProfile = undefined;
            this.router.navigateByUrl('/home');
          };
    

    当然,您包含服务的任何组件也可以像这样在您的html 中调用正确的logout function

    <a class="myClass" href="#"(click)="public.logout()">Logout</a>
    

    <a class="myClass" href="#" (click)="secure.logout()">Logout</a>
    

    【讨论】:

    • 没问题。这有意义吗?和帮助?
    • 事实上,我想出了类似的东西,但想避免将逻辑放在每个组件中,如果你有很多,这可能会有点麻烦。我想没有其他选择:/
    • 你不需要把它放在每个组件中。您可以制作安全模板和公共模板。然后将注销按钮放入模板中。然后在模板中包含页面。因此,任何需要在安全模板中的页面都将是secure.component.ts 的子页面。我已经回答了许多寻找这样的设置的问题。我在这里解释如何做到这一点stackoverflow.com/a/41219564/2218253
    • 如果这回答了您的问题,请接受我的回答正确,并在我的回答中打勾。如果没有,请告诉我有什么不清楚的地方,我会尽力解释以继续为您提供帮助。
    • 我理解你的做法。但它看起来只有在注销按钮位于组件模板(安全或公共)中时才有效。在我的例子中,注销链接位于 NavComponent 中,它是顶级组件,并且对所有子组件(安全或公共)都是通用的。
    【解决方案2】:

    这可以通过单个(菜单)组件来实现,该组件服务于所有公共和私有路由,其中​​私有路由仅在登录时才可见。

    同样的组件还包括一个退出按钮,仅在登录时可见。此处理程序退出并确定当前路由是否需要登录。如果需要,则重定向到主页,如果没有,则不执行任何操作。

    受保护的私有路由可能会在 app.module 中定义 canActivate 定义,因此这些是需要登录的路径。

    app.module.ts

    const appRoutes: Routes = [
      { path: '', component: HomeComponent },
      { path: 'sign-in', component: SignInComponent },
      { path: 'private', loadChildren: './private/private.module#PrivateModule', 
    canActivate: [LoginRouteGuardService] }
    ];
    

    menu.component.ts

    signOut() {
      // your sign out method
      // then check if redirect necessary
      if (this.router.url.includes('/private/')) {
        this.router.navigateByUrl('/');
      }
    }
    

    此处提供的上述变体:https://stackblitz.com/edit/free-vote-redirect-on-sign-out

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-12-18
      • 2016-11-08
      • 2015-08-06
      • 2023-01-18
      • 1970-01-01
      • 2017-12-18
      • 2019-12-16
      • 2020-04-10
      相关资源
      最近更新 更多