snp-connection-monitoring/frontend/src/services/authService.ts
HYOJIN 48671af3c5 feat(phase1): 기반 구축 - DB Entity, JWT 인증, 프론트엔드 레이아웃
백엔드:
- JPA Entity 9개 + Repository 9개 (common 스키마)
- JWT 인증 (jjwt, Access/Refresh 토큰)
- AuthController (login/logout/refresh)
- 공통 모듈 (BaseEntity, ErrorCode, BusinessException, PageResponse)
- SecurityConfig JWT 필터 체인 통합

프론트엔드:
- MainLayout (사이드바 + 헤더) + AuthLayout
- 로그인 페이지 + ProtectedRoute
- API 클라이언트 (fetch wrapper, JWT 자동 첨부, 401 refresh)
- AuthContext + useAuth 훅
- 9개 플레이스홀더 페이지 + 라우팅

설정:
- DB: snp_connection / snp_admin / common 스키마
- ddl-auto: update (개발), validate (운영)

Closes #6

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 13:52:25 +09:00

68 lines
1.8 KiB
TypeScript

import { post } from './apiClient';
import type { LoginRequest, LoginResponse, User } from '../types/auth';
const TOKEN_KEY = 'snp_access_token';
const REFRESH_TOKEN_KEY = 'snp_refresh_token';
const USER_KEY = 'snp_user';
export const login = async (req: LoginRequest): Promise<LoginResponse> => {
const response = await post<LoginResponse>('/auth/login', req);
if (!response.success || !response.data) {
throw new Error(response.message || '로그인에 실패했습니다.');
}
const data = response.data;
localStorage.setItem(TOKEN_KEY, data.accessToken);
localStorage.setItem(REFRESH_TOKEN_KEY, data.refreshToken);
localStorage.setItem(USER_KEY, JSON.stringify({
loginId: data.loginId,
userName: data.userName,
role: data.role,
}));
return data;
};
export const logout = async (): Promise<void> => {
try {
await post('/auth/logout');
} finally {
localStorage.removeItem(TOKEN_KEY);
localStorage.removeItem(REFRESH_TOKEN_KEY);
localStorage.removeItem(USER_KEY);
}
};
export const refreshToken = async (): Promise<void> => {
const storedRefreshToken = localStorage.getItem(REFRESH_TOKEN_KEY);
if (!storedRefreshToken) {
throw new Error('No refresh token available');
}
const response = await post<{ accessToken: string }>('/auth/refresh', {
refreshToken: storedRefreshToken,
});
if (!response.success || !response.data) {
throw new Error('Token refresh failed');
}
localStorage.setItem(TOKEN_KEY, response.data.accessToken);
};
export const getStoredUser = (): User | null => {
const userStr = localStorage.getItem(USER_KEY);
if (!userStr) return null;
try {
return JSON.parse(userStr) as User;
} catch {
return null;
}
};
export const getAccessToken = (): string | null => {
return localStorage.getItem(TOKEN_KEY);
};