Angular Authentication: Using Route Guards

What are Route Guards?

  • CanActivate
  • CanActivateChild
  • CanDeactivate
  • CanLoad
  • Resolve

Routing Decisions Based on Token Expiration

npm install --save @auth0/angular-jwt
// src/app/auth/auth.service.tsimport { Injectable } from '@angular/core';
import { JwtHelperService } from '@auth0/angular-jwt';
@Injectable()
export class AuthService {
constructor(public jwtHelper: JwtHelperService) {} // ...
public isAuthenticated(): boolean {
const token = localStorage.getItem('token'); // Check whether the token is expired and return
// true or false
return !this.jwtHelper.isTokenExpired(token);
}
}
// src/app/auth/auth-guard.service.tsimport { Injectable } from '@angular/core';
import { Router, CanActivate } from '@angular/router';
import { AuthService } from './auth.service';
@Injectable()
export class AuthGuardService implements CanActivate {
constructor(public auth: AuthService, public router: Router) {} canActivate(): boolean {
if (!this.auth.isAuthenticated()) {
this.router.navigate(['login']);
return false;
}
return true;
}
}
// src/app/app.routes.tsimport { Routes, CanActivate } from '@angular/router';
import { ProfileComponent } from './profile/profile.component';
import {
AuthGuardService as AuthGuard
} from './auth/auth-guard.service';
export const ROUTES: Routes = [
{ path: '', component: HomeComponent },
{
path: 'profile',
component: ProfileComponent,
canActivate: [AuthGuard]
},
{ path: '**', redirectTo: '' }
];

Checking for a User’s Role

npm install --save jwt-decode
// src/app/auth/role-guard.service.tsimport { Injectable } from '@angular/core';
import {
Router,
CanActivate,
ActivatedRouteSnapshot
} from '@angular/router';
import { AuthService } from './auth.service';
import decode from 'jwt-decode';
@Injectable()
export class RoleGuardService implements CanActivate {
constructor(public auth: AuthService, public router: Router) {} canActivate(route: ActivatedRouteSnapshot): boolean { // this will be passed from the route config
// on the data property
const expectedRole = route.data.expectedRole;
const token = localStorage.getItem('token'); // decode the token to get its payload
const tokenPayload = decode(token);
if (
!this.auth.isAuthenticated() ||
tokenPayload.role !== expectedRole
) {
this.router.navigate(['login']);
return false;
}
return true;
}
}
// src/app/app.routes.tsimport { Routes, CanActivate } from '@angular/router';
import { ProfileComponent } from './profile/profile.component';
import {
AuthGuardService as AuthGuard
} from './auth/auth-guard.service';
import {
RoleGuardService as RoleGuard
} from './auth/role-guard.service';
export const ROUTES: Routes = [
{ path: '', component: HomeComponent },
{
path: 'profile',
component: ProfileComponent,
canActivate: [AuthGuard]
},
{
path: 'admin',
component: AdminComponent,
canActivate: [RoleGuard],
data: {
expectedRole: 'admin'
}
},
{ path: '**', redirectTo: '' }
];

Isn’t this Easily Hackable?

But I Want to Lock Routes Down Completely

Wrapping Up

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store