14th June 2024
Auth Guard in Angular: Implementing Authentication in Angular using Guards
Introduction
Authentication is a crucial part of web applications to secure resources and restrict unauthorized access. Angular provides a robust framework for implementing authentication, with Auth Guards playing a central role. This article explores how authentication is done in Angular, focusing on Auth Guards, and provides an example project to illustrate the concepts.
Understanding Angular Authentication
Angular authentication typically involves the following components:
- Auth Service: Manages authentication logic like login, logout, and checking the authentication state.
- Auth Guard: Protects routes by allowing access only to authenticated users.
- Interceptor: Intercepts HTTP requests to add authentication tokens.
Setting Up the Example Project
1. Create a New Angular Project
ng new angular-auth-example
cd angular-auth-example
2. Install Dependencies
npm install @angular/material @angular/cdk @angular/animations
npm install @auth0/angular-jwt
Step-by-Step Implementation
1. Create Auth Service
The Auth Service will handle login, logout, and check authentication status.
// src/app/services/auth.service.ts
import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { BehaviorSubject, Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class AuthService {
private loggedIn = new BehaviorSubject<boolean>(false);
constructor(private router: Router) { }
login(username: string, password: string): boolean {
if (username === 'user' && password === 'password') {
localStorage.setItem('token', 'fake-jwt-token');
this.loggedIn.next(true);
return true;
}
return false;
}
logout(): void {
localStorage.removeItem('token');
this.loggedIn.next(false);
this.router.navigate(['/login']);
}
isLoggedIn(): Observable<boolean> {
return this.loggedIn.asObservable();
}
}
2. Create Auth Guard
The Auth Guard will protect routes by checking the user's authentication status
// src/app/guards/auth.guard.ts
import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from '@angular/router';
import { Observable } from 'rxjs';
import { AuthService } from '../services/auth.service';
import { map, take } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivate {
constructor(private authService: AuthService, private router: Router) { }
canActivate(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): Observable<boolean> {
return this.authService.isLoggedIn().pipe(
take(1),
map((isLoggedIn: boolean) => {
if (!isLoggedIn) {
this.router.navigate(['/login']);
return false;
}
return true;
})
);
}
}
3. Configure Routes
Define routes and apply the Auth Guard to protected routes.
// src/app/app-routing.module.ts
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { HomeComponent } from './components/home/home.component';
import { LoginComponent } from './components/login/login.component';
import { AuthGuard } from './guards/auth.guard';
const routes: Routes = [
{ path: 'home', component: HomeComponent, canActivate: [AuthGuard] },
{ path: 'login', component: LoginComponent },
{ path: '**', redirectTo: 'login' }
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
4. Create Login and Home Components
Generate components and implement basic templates and logic.
ng generate component components/login
ng generate component components/home
Login Component
// src/app/components/login/login.component.ts
import { Component } from '@angular/core';
import { Router } from '@angular/router';
import { AuthService } from '../../services/auth.service';
@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.css']
})
export class LoginComponent {
username: string;
password: string;
error: string;
constructor(private authService: AuthService, private router: Router) { }
login(): void {
if (this.authService.login(this.username, this.password)) {
this.router.navigate(['/home']);
} else {
this.error = 'Invalid credentials';
}
}
}
Login Template
<!-- src/app/components/login/login.component.html -->
<div>
<h2>Login</h2>
<form (ngSubmit)="login()">
<label for="username">Username:</label>
<input type="text" id="username" [(ngModel)]="username" name="username">
<br>
<label for="password">Password:</label>
<input type="password" id="password" [(ngModel)]="password" name="password">
<br>
<button type="submit">Login</button>
<p *ngIf="error">{{ error }}</p>
</form>
</div>
Home Component
// src/app/components/home/home.component.ts
import { Component } from '@angular/core';
import { AuthService } from '../../services/auth.service';
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css']
})
export class HomeComponent {
constructor(private authService: AuthService) { }
logout(): void {
this.authService.logout();
}
}
Home Template
<!-- src/app/components/home/home.component.html -->
<div>
<h2>Home</h2>
<button (click)="logout()">Logout</button>
</div>
5. Update App Module
Import necessary modules and declare components.
// src/app/app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { LoginComponent } from './components/login/login.component';
import { HomeComponent } from './components/home/home.component';
import { AuthService } from './services/auth.service';
import { AuthGuard } from './guards/auth.guard';
@NgModule({
declarations: [
AppComponent,
LoginComponent,
HomeComponent
],
imports: [
BrowserModule,
FormsModule,
AppRoutingModule
],
providers: [AuthService, AuthGuard],
bootstrap: [AppComponent]
})
export class AppModule { }
Conclusion
In this article, we have explored how to implement authentication in Angular using Auth Guards. We created an example project to demonstrate the key concepts, including the Auth Service, Auth Guard, and basic routing for protected and public routes. This approach provides a robust foundation for securing Angular applications and can be extended to include more advanced features like role-based access control and token-based authentication.