Angular Route Guards: ป้องกันหน้าที่ต้อง Login ก่อนเข้า

#angular12 เม.ย. 2569

Route Guard คืออะไร

Route Guard ใช้ป้องกันไม่ให้ user เข้าถึงหน้าที่ไม่มีสิทธิ์ เช่น หน้า admin ที่ต้อง login ก่อน

ประเภทของ Guard

  • canActivate — ป้องกันการเข้าถึง route
  • canActivateChild — ป้องกัน child routes
  • canDeactivate — ป้องกันการออกจาก route (เช่น form ที่ยังไม่ save)
  • canMatch — ป้องกันการ match route

สร้าง Auth Guard

// auth.guard.ts
import { inject } from '@angular/core';
import { Router, CanActivateFn } from '@angular/router';
import { AuthService } from './auth.service';

export const authGuard: CanActivateFn = (route, state) => {
  const authService = inject(AuthService);
  const router = inject(Router);

  if (authService.isLoggedIn()) {
    return true;
  }

  // redirect ไป login พร้อม returnUrl
  return router.createUrlTree(['/login'], {
    queryParams: { returnUrl: state.url }
  });
};

ใช้ Guard กับ Routes

export const routes: Routes = [
  { path: 'login', component: LoginComponent },
  {
    path: 'dashboard',
    component: DashboardComponent,
    canActivate: [authGuard]
  },
  {
    path: 'admin',
    component: AdminComponent,
    canActivate: [authGuard, adminGuard]
  }
];

Role-based Guard

export const roleGuard = (requiredRole: string): CanActivateFn => {
  return () => {
    const authService = inject(AuthService);
    const router = inject(Router);

    if (authService.hasRole(requiredRole)) {
      return true;
    }

    return router.createUrlTree(['/forbidden']);
  };
};

// ใช้งาน
{ path: 'admin', canActivate: [roleGuard('admin')] }

canDeactivate Guard

export const unsavedChangesGuard: CanDeactivateFn<EditComponent> = (component) => {
  if (component.hasUnsavedChanges()) {
    return confirm('มีการเปลี่ยนแปลงที่ยังไม่ได้บันทึก ต้องการออกไหม?');
  }
  return true;
};

สรุป

Route Guards เป็นวิธีที่ clean ที่สุดในการจัดการ authorization ใน Angular ควรใช้ functional guard (Angular 15+) แทน class-based guard ครับ