jwt 로그인 구현 진행 : axios 로 api 호출하여 생성된 쿠키로 인증상태값 변경기능 구현

This commit is contained in:
2025-12-31 19:39:42 +09:00
parent fd40ce5e75
commit 985ba75d34
12 changed files with 340 additions and 35 deletions

144
src/context/AuthContext.tsx Normal file
View File

@@ -0,0 +1,144 @@
import React, { createContext, useReducer, useEffect } from 'react';
import { getCurrentUser, isTokenValid } from 'src/axios/authService';
// 사용자 타입 정의
export interface Member {
memberId: string;
memberName: string;
}
// 인증 상태 타입 정의
interface AuthState {
isAuthenticated: boolean;
member: Member | null;
loading: boolean;
error: string | null;
}
// 액션 타입 정의
type AuthAction =
| { type: 'LOGIN_SUCCESS'; payload: { member: Member; token: string } }
| { type: 'LOGOUT' }
| { type: 'AUTH_ERROR'; payload: string }
| { type: 'CLEAR_ERROR' }
| { type: 'SET_LOADING' }
| { type: 'MEMBER_LOADED'; payload: Member };
// 초기 상태
const initialState: AuthState = {
isAuthenticated: false,
member: null,
loading: true,
error: null
};
// Context 생성
export const AuthContext = createContext<{
state: AuthState;
dispatch: React.Dispatch<AuthAction>;
login: (token: string, member: Member) => void;
logout: () => void;
}>({
state: initialState,
dispatch: () => null,
login: () => null,
logout: () => null
});
// 리듀서 함수
const authReducer = (state: AuthState, action: AuthAction): AuthState => {
switch (action.type) {
case 'LOGIN_SUCCESS':
localStorage.setItem('accessToken', action.payload.token);
return {
...state,
isAuthenticated: true,
member: action.payload.member,
loading: false,
error: null
};
case 'LOGOUT':
localStorage.removeItem('accessToken');
return {
...state,
isAuthenticated: false,
member: null,
loading: false,
error: null
};
case 'AUTH_ERROR':
localStorage.removeItem('accessToken');
return {
...state,
isAuthenticated: false,
member: null,
loading: false,
error: action.payload
};
case 'CLEAR_ERROR':
return {
...state,
error: null
};
case 'SET_LOADING':
return {
...state,
loading: true
};
case 'MEMBER_LOADED':
return {
...state,
isAuthenticated: true,
member: action.payload,
loading: false
};
default:
return state;
}
};
// Provider 컴포넌트
export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
const [state, dispatch] = useReducer(authReducer, initialState);
// 로그인 함수
const login = (token: string, member: Member) => {
dispatch({
type: 'LOGIN_SUCCESS',
payload: { token, member }
});
};
// 로그아웃 함수
const logout = () => {
dispatch({ type: 'LOGOUT' });
};
// 초기 인증 상태 확인
useEffect(() => {
const loadUser = async () => {
const token = localStorage.getItem('accessToken');
if (!token || !isTokenValid(token)) {
dispatch({ type: 'LOGOUT' });
return;
}
try {
const member = await getCurrentUser();
dispatch({ type: 'MEMBER_LOADED', payload: member });
} catch (error) {
dispatch({ type: 'AUTH_ERROR', payload: 'Authentication failed' });
}
};
loadUser();
}, []);
return (
<AuthContext.Provider value={{ state, dispatch, login, logout }}>
{children}
</AuthContext.Provider>
);
};