Angular2 : Redirect to another route conditionally when logout

3.7k views Asked by At

I am struggling a bit on a particular use case with Angular2 and the router.

Let's say we have 3 routes. Home, List and Profile.

"Profile" is a guarded route : user has to be authenticated to access this route.

If user is on "Profile" page and logs out, I want to be able to detect that he is not allowed anymore to be on the current page, and redirect him to "Home" page.

However if he is on "List" page and logs out, I don't want to do anything (user is allowed to stay here as it's not a guarded route).

Do someone know how I can achieve that, assuming that I have many routes and I want to avoid to put this "user-is-allowed" logic in each component ?

2

There are 2 answers

15
wuno On BEST ANSWER

Summary

In my case I like to give my user's access to the Guarded routes by checking the validation of a token I save to local storage. So if I log them out I remove the token along with any data I currently have in local storage. You can use this function in each route.

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

I create a service for authentication. You could create two different services, or two different functions. Really you have a lot of options. Here is one option.

Solution

To logout and redirect,

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

You could use this function in each one of your components. Or pages. Basically redirect the route if the user is on the profile page. but if the user is not on a page or route that needs to be redirected then remove the

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

From the function so the user is not redirected.

So you could have two services

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

Then in your pages that you want to log the user out but leave them on the same page use this service

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

So when the use the logout function it wont redirect.

Then to redirect when the user logs out add this service like this,

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

And of course any component you include the service too you call the correct logout function in your html like this,

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

or

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

This can be achieved with a single (menu) component which serves all routes, public and private where the private routes are only made visible when signed in.

This same component also includes a sign out button, only visible if signed in. The handler for this signs out and determines whether the current route requires sign in. If it does, redirect to home page, if not do nothing.

The guarded private routes will probably be defined in app.module with canActivate defined, so these are the paths that require sign in.

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('/');
  }
}

Variation on the above provided here: https://stackblitz.com/edit/free-vote-redirect-on-sign-out