Angular2:注销时有条件地重定向到另一条路线

Angular2 : Redirect to another route conditionally when logout

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

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

"Profile" 是受保护的路由:用户必须经过身份验证才能访问此路由。

如果用户在 "Profile" 页面上并注销,我希望能够检测到他不再被允许在当前页面上,并将他重定向到 "Home" 页面。

但是,如果他在 "List" 页面并注销,我不想做任何事情(允许用户留在这里,因为它不是受保护的路线)。

有人知道我如何实现吗,假设我有很多路由并且我想避免在每个组件中放置这个 "user-is-allowed" 逻辑?

总结

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

  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>

这可以通过为所有路由提供服务的单个(菜单)组件来实现,public 并且私有路由仅在登录时可见。

这个相同的组件还包括一个注销按钮,只有在登录后才可见。注销的处理程序并确定当前路由是否需要登录。如果需要,则重定向到主页,否则什么都不做.

受保护的私有路由可能会在 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