Angular’da Guard Kullanımı

ismail kaşan
4 min readOct 22, 2024

--

Angular’da Guard Kullanımı

Angular’da guard’lar, belirli route’lara erişimi kontrol etmek ve routing işlemlerini yönetmek için kullanılır. Guard’lar, bir kullanıcı veya bir koşulun belirli bir route’a erişimini sağlamak veya engellemek için kontroller sağlar. Angular’da yaygın olarak kullanılan dört tür guard interface’i vardır: CanActivate, CanActivateChild, CanDeactivate, ve CanLoad. Bu guard'lar, kullanıcı yetkilendirmesi, kimlik doğrulama, veri doğrulama gibi işlemleri gerçekleştirmek için kullanılır.

1. CanActivate

CanActivate guard'ı, bir kullanıcı belirli bir route’a erişmeden önce çalışır. Eğer guard “true ”dönerse, kullanıcı route’a erişebilir; “false ”dönerse, erişim engellenir. Genelde kullanıcının oturum açıp açmadığını kontrol etmek, kullanıcının belirli bir role sahip olup olmadığını kontrol etmek için kullanılır. Guard aslında “injectible” bir servistir. Yapacağı işe ve senaryoya göre yukarıdaki interface’lerinden birini implement eder.

Örnek:

// auth.guard.ts
import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from '@angular/router';
import { Observable } from 'rxjs';
import { AuthService } from './auth.service'; // AuthService'yi varsayıyoruz

@Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivate { // implement canActivate
constructor(private authService: AuthService, private router: Router) {}
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): boolean {
if (this.authService.isLoggedIn()) {
return true;
} else {
this.router.navigate(['/login']);
return false;
}
}
}

Oluşturulan guard’ı routing-module içerisinde hangi route’a işlem yapacaksa aşağıdaki gibi eklenir. Bu route’a tıklandığı zaman guard içindeki kodlar işletilir. Eğer guard “true ”dönerse routing işlemi devam eder. Eğer “false ”dönerse routing işlemi yapılmaz.

// app-routing.module.ts
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { HomeComponent } from './home/home.component';
import { LoginComponent } from './login/login.component';
import { AuthGuard } from './auth.guard';

const routes: Routes = [
{ path: '', component: HomeComponent },
{
path: 'home',
component: HomeComponent,
canActivate: [AuthGuard] // ad here
},
{ path: 'login', component: LoginComponent }
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }

2. CanActivateChild

CanActivateChild guard'ı, bir kullanıcı belirli bir route’un child route’ına erişmeden önce çalışır. Eğer guard “true ”dönerse, kullanıcı child route’a erişebilir; “false ”dönerse, erişim engellenir. Admin paneli gibi, bir ana route’un altındaki tüm child route’lara erişim kontrolü sağlamak için kullanılır.

Örnek:

import { Injectable } from '@angular/core';
import { CanActivateChild, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from '@angular/router';
import { AuthService } from './auth.service';

@Injectable({
providedIn: 'root'
})
export class AdminGuard implements CanActivateChild {
constructor(private authService: AuthService, private router: Router) {}

canActivateChild(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): boolean {
if (this.authService.isAdmin()) {
return true;
} else {
this.router.navigate(['/login']);
return false;
}
}
}

Routing module içerisinde bir route’a verilmesi.

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { AdminComponent } from './admin/admin.component';
import { DashboardComponent } from './admin/dashboard/dashboard.component';
import { SettingsComponent } from './admin/settings/settings.component';
import { AdminGuard } from './admin.guard';

const routes: Routes = [
{ path: 'admin', component: AdminComponent, canActivateChild: [AdminGuard],
children: [
{ path: 'dashboard', component: DashboardComponent },
{ path: 'settings', component: SettingsComponent }
]}
];

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

3. CanDeactivate

CanDeactivate guard'ı, bir kullanıcı mevcut bir route’tan ayrılmadan önce çalışır. Bu guard, kullanıcının mevcut route’tan çıkmasına izin verip vermeyeceğini kontrol eder. Genellikle, kullanıcıyı kaydedilmemiş değişiklikler konusunda uyarmak için kullanılır. Kullanıcı bir formu dolduruyorsa ve sayfadan çıkmak isterse, kaydedilmemiş değişiklikler konusunda uyarı vermek için kullanılır.

Örnek:

Genelde bir component ile kullanılır. Öncelikler bu işlemi yapacak component’in implement edeceği bir interface hazırlanır. Daha sonra bu interface CanDeactivate gurd’ına generic olarak veriliyor.

import { Injectable } from '@angular/core';
import { CanDeactivate } from '@angular/router';
import { Observable } from 'rxjs';

export interface CanComponentDeactivate {
canDeactivate: () => Observable<boolean> | Promise<boolean> | boolean;
}

@Injectable({
providedIn: 'root'
})
export class CanDeactivateGuard implements CanDeactivate<CanComponentDeactivate> {
canDeactivate(
component: CanComponentDeactivate
): Observable<boolean> | Promise<boolean> | boolean {
return component.canDeactivate ? component.canDeactivate() : true;
}
}

İşlemi kontrol edilecek component bu oluşturulan interface’i implement ederek kendi işlemini yapar.

export class EditComponent implements CanComponentDeactivate {
canDeactivate(): boolean {
if (this.form.dirty) {
return confirm('You have unsaved changes. Do you really want to leave?');
}
return true;
}
}

Routing module içerisinde bir route’a verilmesi.

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { EditComponent } from './edit/edit.component';
import { CanDeactivateGuard } from './can-deactivate.guard';

const routes: Routes = [
{
path: 'edit',
component: EditComponent,
canDeactivate: [CanDeactivateGuard]
}
];

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

4. CanLoad

CanLoad guard'ı, bir kullanıcı bir modülün yüklenmesini talep etmeden önce çalışır. Eğer guard “true ”dönerse, modül yüklenir; “false ”dönerse, yüklenmez. Bu guard, genellikle lazy-loading modüller için kullanılır. Genellikle, kullanıcının belirli bir modüle erişim yetkisini kontrol etmek için kullanılır.

Örnek:

import { Injectable } from '@angular/core';
import { CanLoad, Route, UrlSegment, Router } from '@angular/router';
import { AuthService } from './auth.service';

@Injectable({
providedIn: 'root'
})
export class AuthCanLoadGuard implements CanLoad {
constructor(private authService: AuthService, private router: Router) {}

canLoad(
route: Route,
segments: UrlSegment[]
): boolean {
if (this.authService.isLoggedIn()) {
return true;
} else {
this.router.navigate(['/login']);
return false;
}
}
}

Routing module içerisinde bir route’a verilmesi.

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { AuthCanLoadGuard } from './auth-can-load.guard';

const routes: Routes = [
{ path: 'admin',
loadChildren: () => import('./admin/admin.module').then(m => m.AdminModule),
canLoad: [AuthCanLoadGuard] // added here
}
];

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

Toparlayacak olursak, bu 4 ana guar’dın her birinin bir kullanım senayorsuna göre kullanım amacı vardır. Bu guard’lar, uygulamanızın farklı bölümlerine erişimi etkin bir şekilde yönetmek için kullanılır ve kullanıcı deneyimini güvenli ve düzenli hale getirir.

Yazıyı, yeni başlayanlar veya İngilizcesi yeterli olmayanlar için mümkün olduğunca anlaşılır bir şekilde yazmaya çalıştım. Umarım faydalı olmuştur. Aklınıza takılan herhangi bir soruyu çekinmeden yorumlarda sorabilirsiniz.

Yaralanılan Kaynaklar:

--

--

ismail kaşan
ismail kaşan

Written by ismail kaşan

I am a full stack developer since 2016.

No responses yet