본문 바로가기

개발 공부/Angular

Angular Router Guards

Angular Functional Router Guards: 간결하고 효율적인 라우터 보호 방법

Angular 15부터 Functional Router Guards가 도입되면서, 기존의 클래스 기반 Guard보다 더 간단하고 명확한 방식으로 라우터 접근 제어를 설정할 수 있게 되었습니다.

 

Router Guard

Router Guard는 Angular 라우팅에서 특정 경로에 사용자가 접근하기 전에 조건을 확인하고, 그 조건에 따라 접근을 허용하거나 차단하는 메커니즘입니다.

사용 시나리오

  • 사용자가 로그인되어 있어야 특정 페이지에 접근 가능.
  • 특정 권한(Role)이 있는 사용자만 특정 경로를 볼 수 있음.
  • 사용자가 입력을 저장하지 않고 페이지를 벗어나려 할 때 경고 메시지 표시.

주요 종류

  • CanActivate: 라우트에 접근할 수 있는지 여부를 결정.
  • CanDeactivate: 사용자가 현재 페이지를 떠날 수 있는지 여부를 결정.

 

Functional Router Guard 소개

기존에는 Guard를 만들기 위해 클래스를 정의해야 했습니다. 그러나 Angular 15에서 함수형 Guard가 도입되면서, 단순히 함수를 정의하여 라우트 접근 조건을 명시할 수 있게 되었습니다.

장점

  • 코드가 간결하고 직관적임.
  • 의존성 주입이 더 쉬워짐.
  • 유지보수성이 향상됨.

 

구체적인 구현 예시

기존 클래스 기반 Guard

import { Injectable } from '@angular/core';
import { CanActivate } from '@angular/router';
import { AuthService } from './auth.service';

@Injectable({
  providedIn: 'root',
})
export class AuthGuard implements CanActivate {
  constructor(private authService: AuthService) {}

  canActivate(): boolean {
    return this.authService.isAuthenticated();
  }
}

 

  • AuthGuard 클래스는 CanActivate 인터페이스를 구현하여, 사용자가 인증되었는지 확인하고 boolean 값을 반환합니다.

 

함수형 Guard

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

export const authGuard: CanActivateFn = () => {
  const authService = inject(AuthService);
  return authService.isAuthenticated();
};
  • 함수형 Guard는 더 간결합니다. inject()를 사용해 필요한 의존성을 주입하고, 인증 상태를 확인하여 boolean 값을 반환합니다.

라우터 설정에서 사용

함수형 Guard를 실제 라우터 설정에서 사용하는 방법은 다음과 같습니다.

import { Routes } from '@angular/router';
import { authGuard } from './auth.guard';
import { DashboardComponent } from './dashboard/dashboard.component';

const routes: Routes = [
  {
    path: 'dashboard',
    component: DashboardComponent,
    canActivate: [authGuard], // 함수형 Guard를 등록
  },
];
  • canActivate 배열에 Guard를 추가하여, 라우트 접근 여부를 결정합니다.

 

Functional Guard의 장점

  1. 간결함: 별도의 클래스를 생성하지 않아도 Guard를 정의 가능.
  2. 의존성 주입 간소화: inject()를 통해 서비스 및 종속성을 직접 주입.
  3. 코드 유지보수성 증가: Guard가 단순 함수로 구성되어 가독성이 높음.
  4. 유연성: Guard 내부에서 라우팅 또는 상태 관리를 유연하게 처리 가능.

간단 예시 : 인증된 사용자만 대시보드 페이지에 접근하도록 설정하기

 

1. AuthService 구현

먼저, 사용자의 인증 상태를 확인할 수 있는 서비스가 필요합니다.

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root',
})
export class AuthService {
  private loggedIn = false; // 기본값은 로그아웃 상태

  // 사용자가 로그인했는지 확인
  isAuthenticated(): boolean {
    return this.loggedIn;
  }

  // 로그인/로그아웃 상태 변경
  login() {
    this.loggedIn = true;
  }

  logout() {
    this.loggedIn = false;
  }
}

 

2. Functional Router Guard 정의

이제 함수형 Guard를 만들어, 사용자가 인증되지 않은 경우 접근을 막아보겠습니다.

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

export const authGuard: CanActivateFn = () => {
  const authService = inject(AuthService); // AuthService 주입

  // 사용자가 인증 상태인지 확인
  if (authService.isAuthenticated()) {
    return true; // 인증된 경우 접근 허용
  } else {
    console.log('접근이 거부되었습니다. 로그인하세요!');
    return false; // 인증되지 않은 경우 접근 차단
  }
};

 

3. 라우터 설정

authGuard를 Angular의 라우터 설정에 추가합니다.

import { Routes } from '@angular/router';
import { authGuard } from './auth.guard';
import { DashboardComponent } from './dashboard/dashboard.component';

const routes: Routes = [
  {
    path: 'dashboard',
    component: DashboardComponent,
    canActivate: [authGuard], // authGuard를 경로에 연결
  },
];

 

4. 데모 실행

  • 로그인되지 않은 상태에서 /dashboard로 이동하려고 하면, authGuard가 false를 반환하므로 접근이 차단됩니다.
  • 로그인된 상태에서 /dashboard로 이동하려고 하면, authGuard가 true를 반환하므로 접근이 허용됩니다.

작동 예제

1. 인증되지 않은 경우

사용자가 /dashboard로 접근하려고 하면, 아래와 같은 로그가 출력됩니다

접근이 거부되었습니다. 로그인하세요!

 

그리고 페이지는 로드되지 않습니다.

2. 인증된 경우

사용자가 로그인한 후 /dashboard에 접근하면, 페이지가 정상적으로 표시됩니다.

'개발 공부 > Angular' 카테고리의 다른 글

ng-container / Angular (1)  (1) 2024.12.01
Query Parameters / Angular  (1) 2024.11.26
NgRx Component Store: 컴포넌트 중심의 상태 관리  (0) 2024.11.23
Angular Signals (2)  (0) 2024.11.21
Angular Signals (1)  (1) 2024.11.20