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의 장점
- 간결함: 별도의 클래스를 생성하지 않아도 Guard를 정의 가능.
- 의존성 주입 간소화: inject()를 통해 서비스 및 종속성을 직접 주입.
- 코드 유지보수성 증가: Guard가 단순 함수로 구성되어 가독성이 높음.
- 유연성: 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 |