Published: December 01 2022

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

Tutorial built with Angular 14.2.12

This is a quick post to show how to redirect a user back to the previous URL (the original URL requested) after successful login in an Angular 14 application.

The example code is from an Angular user registration tutorial I posted a few days ago which automatically redirects the user to their requested page after login. For the full tutorial see Angular 14 - User Registration and Login Example & Tutorial.

We'll be looking at these three files which are responsible for the auth and redirect behaviour:

  • AppRoutingModule - configures routes for the app and sets which ones are secure.
  • AuthGuard - route guard used to protect secure routes and provide return url.
  • LoginComponent - component for handling authentication and redirection.


App Routing Module

Path: /src/app/app-routing.module.ts

The app routing module defines the top level routes for the angular application and generates a root routing module by passing the array of routes to the RouterModule.forRoot() method.

The home route maps the base path of the app to the HomeComponent, the users route maps to the usersModule and the account route maps to the accountModule, both module routes (/users and /account) are lazy loaded.

Routes secured with AuthGuard

The home and users routes are secured by passing the auth guard to the canActivate property of each route.

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

import { HomeComponent } from './home';
import { AuthGuard } from './_helpers';

const accountModule = () => import('./account/account.module').then(x => x.AccountModule);
const usersModule = () => import('./users/users.module').then(x => x.UsersModule);

const routes: Routes = [
    { path: '', component: HomeComponent, canActivate: [AuthGuard] },
    { path: 'users', loadChildren: usersModule, canActivate: [AuthGuard] },
    { path: 'account', loadChildren: accountModule },

    // otherwise redirect to home
    { path: '**', redirectTo: '' }
];

@NgModule({
    imports: [RouterModule.forRoot(routes)],
    exports: [RouterModule]
})
export class AppRoutingModule { }


Angular Auth Guard

Path: /src/app/_helpers/auth.guard.ts

The auth guard is an angular route guard that's used to prevent unauthenticated users from accessing restricted routes, it does this by implementing the CanActivate interface which allows the guard to decide if a route can be activated with the canActivate() method. If the method returns true the route is activated (allowed to proceed), otherwise if the method returns false the route is blocked.

The auth guard uses the accountService to check if the user is logged in, if they are logged in it returns true from the canActivate() method, otherwise it returns false and redirects the user to the login page along with the returnUrl in the query parameters.

Requested URL in RouterStateSnapshot

The returnUrl passed in the query parameters to the login page is the original URL requested by the user, it is accessible to the route guard via the state.url property of the state: RouterStateSnapshot method parameter.

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

import { AccountService } from '@app/_services';

@Injectable({ providedIn: 'root' })
export class AuthGuard implements CanActivate {
    constructor(
        private router: Router,
        private accountService: AccountService
    ) {}

    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
        const user = this.accountService.userValue;
        if (user) {
            // authorised so return true
            return true;
        }

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


Angular Login Component

Path: /src/app/account/login.component.ts

The login component defines form fields and handles authentication when the login form is submitted.

Redirect to return URL on success

On successful login the user is redirected to the return URL provided in the query parameters (this.route.snapshot.queryParams['returnUrl']), or to the home page if no return URL was provided.

import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { first } from 'rxjs/operators';

import { AccountService, AlertService } from '@app/_services';

@Component({ templateUrl: 'login.component.html' })
export class LoginComponent implements OnInit {
    form!: FormGroup;
    loading = false;
    submitted = false;

    constructor(
        private formBuilder: FormBuilder,
        private route: ActivatedRoute,
        private router: Router,
        private accountService: AccountService,
        private alertService: AlertService
    ) { }

    ngOnInit() {
        this.form = this.formBuilder.group({
            username: ['', Validators.required],
            password: ['', Validators.required]
        });
    }

    // convenience getter for easy access to form fields
    get f() { return this.form.controls; }

    onSubmit() {
        this.submitted = true;

        // reset alerts on submit
        this.alertService.clear();

        // stop here if form is invalid
        if (this.form.invalid) {
            return;
        }

        this.loading = true;
        this.accountService.login(this.f.username.value, this.f.password.value)
            .pipe(first())
            .subscribe({
                next: () => {
                    // get return url from query parameters or default to home page
                    const returnUrl = this.route.snapshot.queryParams['returnUrl'] || '/';
                    this.router.navigateByUrl(returnUrl);
                },
                error: error => {
                    this.alertService.error(error);
                    this.loading = false;
                }
            });
    }
}

 


Need Some Angular 14 Help?

Search fiverr for freelance Angular 14 developers.


Follow me for updates

On Twitter or RSS.


When I'm not coding...

Me and Tina are on a motorcycle adventure around Australia.
Come along for the ride!


Comments


Supported by