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
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
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
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
When I'm not coding...
Me and Tina are on a motorcycle adventure around Australia.
Come along for the ride!