December 08 2016

Angular 2 - Redirect to Previous URL after Login with Auth Guard

In this post I'll show you how to redirect a user back to their originally requested url / route after logging into an Angular 2 application, this is done with the help of an Auth Guard and a Login Component.

The code below is part of a larger user registration and login example I posted recently, I created this separate post to describe the redirection behaviour because I couldn't find many clear answers out there that show how to implement it in Angular 2.

To see a working demo of the code go to http://jasonwatmore.com/post/2016/09/29/angular-2-user-registration-and-login-example-tutorial.


Angular 2 Auth Guard

Guards in Angular 2 are used to protect routes, there are a few different guard types depending on the specific behaviour you want to implement, in this example I'm using a CanActivate guard which implements a single canActivate() method that enables you to check if a route can be activated or not, which in this case is if the user is authenticated or not.

The example Auth Guard checks to see if the user is authenticated by simply checking if there's a 'currentUser' object in local storage, if there is it returns true which passes the CanActivate Guard, otherwise it returns false which fails the CanActivate Guard and prevents the route from being activated.

If the user isn't authenticated, the auth guard also redirects them to the '/login' route and includes the original (previous) url in the 'returnUrl' parameter. The original url is accessible in the auth guard via the 'state: RouterStateSnapshot' parameter that is passed to the canActivate() method.

Auth Guard that passes original URL to login component

import { Injectable } from '@angular/core';
import { Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';

@Injectable()
export class AuthGuard implements CanActivate {

    constructor(private router: Router) { }

    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
        if (localStorage.getItem('currentUser')) {
            // logged in so return true
            return true;
        }

        // not logged in so redirect to login page with the return url and return false
        this.router.navigate(['/login'], { queryParams: { returnUrl: state.url }});
        return false;
    }
}


Angular 2 Login Component

The login component is a standard Angular 2 'controller' component that implements the behaviour for a login form.

In the ngOnInit() method the component gets the original url that was passed from the Auth Guard as a route parameter and stores it in the local returnUrl property, if the original url is empty the returnUrl defaults to the home page route ('/'). Parameters for the current route are accessible via the 'private route: ActivatedRoute' property that's injected in the component constructor.

In the login() method the component uses the authenticationService to authenticate the username and password, on successful login the user is redirected to the returnUrl. For more details on the authentication service go to the user registraion and login example link at the top of the post.

Login Component that redirects to the previous / original URL after login

import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';

import { AlertService, AuthenticationService } from '../_services/index';

@Component({
    moduleId: module.id,
    templateUrl: 'login.component.html'
})

export class LoginComponent implements OnInit {
    model: any = {};
    loading = false;
    returnUrl: string;

    constructor(
        private route: ActivatedRoute,
        private router: Router,
        private authenticationService: AuthenticationService,
        private alertService: AlertService) { }

    ngOnInit() {
        // reset login status
        this.authenticationService.logout();

        // get return url from route parameters or default to '/'
        this.returnUrl = this.route.snapshot.queryParams['returnUrl'] || '/';
    }

    login() {
        this.loading = true;
        this.authenticationService.login(this.model.username, this.model.password)
            .subscribe(
                data => {
                    // login successful so redirect to return url
                    this.router.navigateByUrl(this.returnUrl);
                },
                error => {
                    // login failed so display error
                    this.alertService.error(error);
                    this.loading = false;
                });
    }
}

 

Angular 2 Development Consultant Sydney

Feel free to drop me a line if you're looking for an Angular 2 development consultant in Sydney Australia, I also provide remote contracting services for clients outside Sydney.


Sponsored by