๐งฑ ๊ฐ์ 9B : ์ ํ ๊ด๋ฆฌ (Angular)
Source: Dev.to
์์ ์ ๊ณต๋ ์์ค ๋งํฌ๋ง์ผ๋ก๋ ๋ฒ์ญํ ๋ณธ๋ฌธ์ด ์์ต๋๋ค. ๋ฒ์ญ์ด ํ์ํ ์ ์ฒด ํ ์คํธ๋ฅผ ์ ๊ณตํด ์ฃผ์๋ฉด ํ๊ตญ์ด๋ก ๋ฒ์ญํด ๋๋ฆฌ๊ฒ ์ต๋๋ค.
์๊ฐ
์ด ๋ชจ๋์ ์ ์ฒด CRUD ์์ ๊ณผ ํ๋ฐํธ์๋ ์ธํฐํ์ด์ค์ ๋ฐฑ์๋ API ๊ฐ์ ์ํํ ํตํฉ์ ํฌํจํ ์์ ํ ์ ํ ๊ด๋ฆฌ ๊ธฐ๋ฅ ๊ตฌ์ถ์ ์ค์ ์ ๋ก๋๋ค. ์ด๋ฅผ ํตํด ์ฌ์ฉ์๋ ์์คํ ์ ๋ฐ์ ๊ฑธ์ณ ์ํํ๊ณ ๋ฐ์์ฑ์ด ๋ฐ์ด๋ ๊ฒฝํ์ ์ ์งํ๋ฉด์ ์ ํ์ ํจ์จ์ ์ผ๋ก ์์ฑ, ์ ๋ฐ์ดํธ, ์กฐํ ๋ฐ ์ญ์ ํ ์ ์์ต๋๋ค.
๊ด๋ฆฌ์๋ ๋ค์์ ์ํํ ์ ์์ต๋๋ค:
- ์ ํ ๊ด๋ฆฌ
- ์ด๋ฏธ ๊ตฌ์ถํ ๋ฐฑ์๋ API์ ํต์
Topics Covered
- Auth Guard
- ์ ํ์ ๋ํ ์ ์ฒด CRUD ํ์ด์ง
- Product Service
- Product Route
- App Routes ์ ๋ฐ์ดํธ
- ๋ฉ๋ด ์ ๋ฐ์ดํธ
์ธ์ฆ ๊ฐ๋
๊ฒฝ๋ก: src/app/services/authguard/auth-guard.service.ts
import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { AuthApiService } from '../api/auth.service';
@Injectable({
providedIn: 'root'
})
export class AuthGuardService {
constructor(
private authService: AuthApiService,
private router: Router
) {}
canActivate(): boolean {
const token = this.authService.getToken();
const refreshToken = this.authService.getRefreshToken();
// If no token and no refresh token, redirect to login
if (!token && !refreshToken) {
this.router.navigate(['/auth/login']);
return false;
}
// If no token but refresh token exists, try to refresh
if (!token && refreshToken) {
this.attemptTokenRefresh(refreshToken);
return false; // Wait for refresh attempt
}
// If token exists, user is authenticated
if (token) {
return true;
}
return false;
}
private attemptTokenRefresh(refreshToken: string): void {
this.authService.refresh({ token: '', refreshToken }).subscribe({
next: () => {
// Token refreshed successfully, reload current route
this.router.navigate([this.router.url]);
},
error: () => {
// Refresh failed, redirect to login
this.authService.logout();
this.router.navigate(['/auth/login']);
}
});
}
}
PrimeNG์ ์ฌ์ฉํ UI ํ์ด์ง
์ ํ ๊ธฐ๋ฅ์ ์ํด ๋ค์ ์ธ ํ์ผ์ ์์ฑํ์ธ์:
src/app/features/products/product/product.htmlsrc/app/features/products/product/product.scss(๋น ํ์ผ)src/app/features/products/product/product.ts
product.html
Manage Products
ID
Name
Description
Price
Stock
{{ product.id }}
{{ product.name }}
{{ product.description }}
{{ product.price | currency: 'USD' }}
{{ product.stock }}
Name
Name is required.
Description
Price
Stock
product.scss
product.ts
import { Component, OnInit, signal, ViewChild } from '@angular/core';
import { ConfirmationService, MessageService } from 'primeng/api';
import { Table, TableModule } from 'primeng/table';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { ButtonModule } from 'primeng/button';
import { RippleModule } from 'primeng/ripple';
import { ToastModule } from 'primeng/toast';
import { ToolbarModule } from 'primeng/toolbar';
import { RatingModule } from 'primeng/rating';
import { InputTextModule } from 'primeng/inputtext';
import { TextareaModule } from 'primeng/textarea';
import { SelectModule } from 'primeng/select';
import { Radi