Search code examples
angularangular2-routing

Angular2 - Redirect to calling url after successful login


I have my application up and running with Angular 2.1.0. The routes are protected via router Guards, canActivate.

When pointing the browser to a protected area like "localhost:8080/customers" I get redirected to my login page just like expected.

But after a successful login, I would like to be redirected back to calling URL ("/customers" in this case).

The code for handling the login looks like this

login(event, username, password) {
  event.preventDefault();
  var success = this.loginService.login(username, password);
  if (success) {
    console.log(this.router);
    this.router.navigate(['']);
  } else {
    console.log("Login failed, display error to user");
  }
}

The problem is, I don't know how to get a hold of the calling url from inside the login method.

I did find a question (and answer) regarding this but couldn't really make any sense of it. Angular2 Redirect After Login


Solution

  • There's a tutorial in the Angular Docs, Milestone 5: Route guards. One possible way to achieve this is by using your AuthGuard to check for your login status and store the url on your AuthService.

    AuthGuard

    import { Injectable }       from '@angular/core';
    import {
      CanActivate, Router,
      ActivatedRouteSnapshot,
      RouterStateSnapshot
    }                           from '@angular/router';
    import { AuthService }      from './auth.service';
    
    @Injectable()
    export class AuthGuard implements CanActivate {
      constructor(private authService: AuthService, private router: Router) {}
    
      canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
        let url: string = state.url;
    
        return this.checkLogin(url);
      }
    
      checkLogin(url: string): boolean {
        if (this.authService.isLoggedIn) { return true; }
    
        // Store the attempted URL for redirecting
        this.authService.redirectUrl = url;
    
        // Navigate to the login page with extras
        this.router.navigate(['/login']);
        return false;
      }
    }
    

    AuthService or your LoginService

    import { Injectable } from '@angular/core';
    import { Http, Response } from '@angular/http';
    import { Router } from '@angular/router';
    
    @Injectable()
    export class AuthService {
      isLoggedIn: boolean = false;    
      // store the URL so we can redirect after logging in
      public redirectUrl: string;
    
      constructor (
       private http: Http,
       private router: Router
      ) {}
    
      login(username, password): Observable<boolean> {
        const body = {
          username,
          password
        };
        return this.http.post('api/login', JSON.stringify(body)).map((res: Response) => {
          // do whatever with your response
          this.isLoggedIn = true;
          if (this.redirectUrl) {
            this.router.navigate([this.redirectUrl]);
            this.redirectUrl = null;
          }
        }
      }
    
      logout(): void {
        this.isLoggedIn = false;
      }
    }
    

    I think this will give an idea how things work, of course you probably need to adapt to your code