import { ApplicationConfig, importProvidersFrom } from '@angular/core';
import {
provideRouter,
withEnabledBlockingInitialNavigation,
} from '@angular/router';
import { appRoutes } from './app.routes';
import { HTTP_INTERCEPTORS, HttpClientModule } from '@angular/common/http';
import { HttpInterceptorImpl } from './interceptors/http-interceptor'; // interceptor
import { NgxsModule } from '@ngxs/store'; // store
import { AdminStore } from './store/auth.store'; // store
import { IonicModule } from '@ionic/angular'; // ionic
export const appConfig: ApplicationConfig = {
providers: [
provideRouter(appRoutes, withEnabledBlockingInitialNavigation()),
importProvidersFrom(
HttpClientModule,
NgxsModule.forRoot([AdminStore]),
IonicModule.forRoot()
),
{ provide: HTTP_INTERCEPTORS, useClass: HttpInterceptorImpl, multi: true },
],
};
app module
기본 설정
import { Injectable } from '@angular/core';
import { State, Action, StateContext, Selector, NgxsOnInit, Store } from '@ngxs/store';
import { ActivatedRoute, Router } from '@angular/router';
import { HttpService } from '../app/services/http.service';
import { IAuthDTO } from '@aresa/interface'
export class SetAuth {
static readonly type = '[Auth] Set Auth';
constructor(public auth: IAuthDTO) { }
}
export class ResetAuth {
static readonly type = '[Auth] Reset Auth';
constructor() { }
}
export type AuthStateModel = {
auth: IAuthDTO | null
}
@State<AuthStateModel>({
name: 'auth',
defaults: {
auth: {
admin: null,
user: null
},
}
})
@Injectable()
export class AuthState implements NgxsOnInit {
constructor(
private httpService: HttpService,
private readonly store: Store,
private router: Router,
private route: ActivatedRoute
) { }
ngxsOnInit(ctx: StateContext<any>): void {
const accessToken = localStorage.getItem('ACCESS_TOKEN');
if (accessToken) {
this.httpService.get<IAuthDTO>('auth', { headers: { Authorization: `Bearer ${accessToken}` } }).subscribe({
next: (auth) => {
ctx.setState({ auth });
this.store.dispatch(new SetAuth(auth));
}
})
}
}
@Selector()
static isAuthenticated(state: AuthStateModel): boolean {
return !!state.auth
}
@Selector()
static auth(state: AuthStateModel): IAuthDTO | null {
return state.auth;
}
@Action(SetAuth)
setAuth(ctx: StateContext<AuthStateModel>, action: SetAuth) {
ctx.setState({
auth: action.auth
})
}
@Action(ResetAuth)
resetAuth(ctx: StateContext<AuthStateModel>) {
ctx.setState({
auth: null
})
}
}
@Select(AuthState) auth$!: Observable<IAuthDTO>;
해당 코드는 Angular 애플리케이션에서 사용되는 Ngxs(State Management)를 통해 인증 관련 상태를 관리하는 AuthState 클래스입니다. 코드를 하나씩 분석하고 주석으로 설명하겠습니다.
import { Injectable } from '@angular/core';
import { State, Action, StateContext, Selector, NgxsOnInit, Store } from '@ngxs/store';
import { ActivatedRoute, Router } from '@angular/router';
import { HttpService } from '../app/services/http.service';
import { IAuthDTO } from '@aresa/interface'
export class SetAuth {
static readonly type = '[Auth] Set Auth';
constructor(public auth: IAuthDTO) { }
}
export class ResetAuth {
static readonly type = '[Auth] Reset Auth';
constructor() { }
}
SetAuth
와 ResetAuth
액션은 인증(auth)과 관련된 상태를 설정하고 재설정하는 데 사용됩니다.export type AuthStateModel = {
auth: IAuthDTO | null
}
AuthStateModel
은 인증 상태(auth)의 모델을 정의합니다. auth
속성은 IAuthDTO
인터페이스 또는 null
값일 수 있습니다.@State<AuthStateModel>({
name: 'auth',
defaults: {
auth: {
admin: null,
user: null
},
}
})
@Injectable()
export class AuthState implements NgxsOnInit {
// ...
}
AuthState
클래스를 정의합니다. @State
데코레이터를 사용하여 Ngxs 상태로 등록됩니다.name: 'auth'
는 상태의 이름을 auth
로 설정합니다.defaults
속성은 초기 상태를 정의합니다. auth
속성은 admin
과 user
를 null
로 갖는 초기 인증 객체입니다.@Injectable()
데코레이터는 의존성 주입을 위해 AuthState
클래스를 주입 가능한 서비스로 표시합니다.constructor(
private httpService: HttpService,
private readonly store: Store,
private router: Router,
private route: ActivatedRoute
) { }
AuthState
클래스의 생성자입니다. httpService
, store
, router
, route
등의 의존성을 주입받습니다.ngxsOnInit(ctx: StateContext<any>): void {
const accessToken = localStorage.getItem('ACCESS_TOKEN');
if (accessToken) {
this.httpService.get<IAuthDTO>('auth', { headers: { Authorization: `Bearer ${accessToken}` } }).subscribe({
next: (auth) => {
ctx.setState({ auth });
this.store.dispatch(new SetAuth(auth));
}
})
}
}
NgxsOnInit
인터페이스를 구현하여 ngxsOnInit
메서드를 정의합니다. 이 메서드는 상태가 초기화될 때 실행됩니다.ngxsOnInit
메서드는 localStorage
에서 액세스 토큰을 가져와 인증 요청을 보내고, 응답으로 받은 인증 객체를 상태에 설정합니다. 또한 SetAuth
액션을 디스패치하여 상태 업데이트를 알립니다.@Selector()
static isAuthenticated(state: AuthStateModel): boolean {
return !!state.auth
}
@Selector()
static auth(state: AuthStateModel): IAuthDTO | null {
return state.auth;
}
@Selector()
데코레이터를 사용하여 선택자(selector) 메서드를 정의합니다.isAuthenticated
선택자는 auth
상태가 존재하는지 여부를 불리언 값으로 반환합니다.auth
선택자는 현재 인증(auth) 상태 객체를 반환합니다.@Action(SetAuth)
setAuth(ctx: StateContext<AuthStateModel>, action: SetAuth) {
ctx.setState({
auth: action.auth
})
}
@Action(ResetAuth)
resetAuth(ctx: StateContext<AuthStateModel>) {
ctx.setState({
auth: null
})
}
@Action()
데코레이터를 사용하여 액션 핸들러 메서드를 정의합니다.setAuth
액션 핸들러는 인증 객체를 상태에 설정합니다.resetAuth
액션 핸들러는 인증 객체를 null
로 재설정합니다.@Select(AuthState) auth$!: Observable<IAuthDTO>;
@Select()
데코레이터를 사용하여 상태 선택자를 정의합니다. auth$
는 AuthState
상태의 변화를 구독하는 Observable
입니다.코드는 Ngxs를 사용하여 인증 상태를 관리하기 위한 AuthState 클래스를 정의하고 있습니다. 이를 통해 애플리케이션에서 인증 상태를 추적하고 업데이트할 수 있으며, 선택자를 통해 현재 상태를 조회할 수 있습니다.