본문 바로가기
React

React에서 로그인 상태 관리하기

by 굿센스굿 2024. 12. 16.
반응형

 

React 애플리케이션에서 로그인 상태를 관리하는 것은 사용자 경험(UX)을 개선하고 애플리케이션의 보안을 강화하는 핵심 요소 중 하나입니다. 로그인 상태 관리는 단순히 사용자의 로그인 여부를 추적하는 것을 넘어, 세션 만료, 역할 기반 접근 제어(Role-Based Access Control, RBAC) 등을 포함한 복잡한 상태를 처리할 수 있어야 합니다. 이 글에서는 React에서 로그인 상태를 관리하는 다양한 방법과 베스트 프랙티스를 소개합니다.

로그인 상태 관리의 주요 개념

로그인 상태를 관리하기 위해 알아야 할 주요 개념은 다음과 같습니다:

  1. 토큰 기반 인증(Token-Based Authentication):
    • 사용자가 로그인하면 서버에서 JWT(JSON Web Token) 또는 세션 토큰을 발급합니다.
    • 클라이언트는 이 토큰을 저장하고, 인증이 필요한 요청마다 서버로 전달합니다.
  2. 상태 저장(Storage):
    • 로그인 상태를 브라우저의 localStorage, sessionStorage, 혹은 쿠키(Cookies)에 저장할 수 있습니다.
  3. 상태 동기화(State Synchronization):
    • 애플리케이션 전역에서 로그인 상태를 공유하기 위해 React의 상태 관리 도구(예: Context API, Redux)를 사용할 수 있습니다.
  4. 보안 고려 사항:
    • 토큰을 안전하게 저장하고, 필요하지 않을 때는 삭제합니다.
    • XSS(Cross-Site Scripting) 및 CSRF(Cross-Site Request Forgery) 공격에 대비해야 합니다.

로그인 상태 관리 방법

1. React Context API 사용하기

React Context API는 전역 상태를 간단하게 관리할 수 있는 도구로, 로그인 상태를 관리하는 데 유용합니다.

Context API 구현 예제

import React, { createContext, useState, useContext } from 'react';

// AuthContext 생성
const AuthContext = createContext();

// AuthProvider 컴포넌트
export const AuthProvider = ({ children }) => {
  const [isAuthenticated, setIsAuthenticated] = useState(false);

  const login = () => setIsAuthenticated(true);
  const logout = () => setIsAuthenticated(false);

  return (
    <AuthContext.Provider value={{ isAuthenticated, login, logout }}>
      {children}
    </AuthContext.Provider>
  );
};

// Custom Hook
export const useAuth = () => useContext(AuthContext);

위 코드는 로그인 상태를 관리하기 위해 AuthContext를 생성하고, AuthProvider를 통해 상태를 자식 컴포넌트에 제공합니다. useAuth 훅을 사용하여 어디서든 로그인 상태에 접근할 수 있습니다.

사용 예제

import React from 'react';
import { useAuth } from './AuthProvider';

const Navbar = () => {
  const { isAuthenticated, login, logout } = useAuth();

  return (
    <nav>
      {isAuthenticated ? (
        <button onClick={logout}>Logout</button>
      ) : (
        <button onClick={login}>Login</button>
      )}
    </nav>
  );
};

export default Navbar;

2. Redux를 사용한 상태 관리

Redux는 애플리케이션의 상태를 전역적으로 관리할 수 있는 강력한 도구입니다. 복잡한 로그인 상태 로직(예: 역할 기반 접근 제어)을 처리해야 할 때 적합합니다.

Redux 설정 예제

  1. 상태 Slice 작성:
import { createSlice } from '@reduxjs/toolkit';

const authSlice = createSlice({
  name: 'auth',
  initialState: { isAuthenticated: false },
  reducers: {
    login: (state) => {
      state.isAuthenticated = true;
    },
    logout: (state) => {
      state.isAuthenticated = false;
    },
  },
});

export const { login, logout } = authSlice.actions;
export default authSlice.reducer;
  1. 스토어 설정:
import { configureStore } from '@reduxjs/toolkit';
import authReducer from './authSlice';

const store = configureStore({
  reducer: {
    auth: authReducer,
  },
});

export default store;
  1. 컴포넌트에서 상태 사용:
import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { login, logout } from './authSlice';

const Navbar = () => {
  const isAuthenticated = useSelector((state) => state.auth.isAuthenticated);
  const dispatch = useDispatch();

  return (
    <nav>
      {isAuthenticated ? (
        <button onClick={() => dispatch(logout())}>Logout</button>
      ) : (
        <button onClick={() => dispatch(login())}>Login</button>
      )}
    </nav>
  );
};

export default Navbar;

3. 토큰 저장 위치와 보안 고려 사항

  • localStorage:
    • 새로고침 후에도 로그인 상태를 유지할 수 있습니다.
    • 하지만 XSS 공격에 취약하므로 민감한 정보를 저장하지 않는 것이 좋습니다.
  • 쿠키(Cookies):
    • HTTP Only 및 Secure 속성을 설정하여 보안을 강화할 수 있습니다.
    • CSRF 공격 방지를 위해 적절한 조치를 취해야 합니다.
  • sessionStorage:
    • 브라우저 탭을 닫으면 데이터가 삭제됩니다.
    • 짧은 세션을 유지할 때 유용합니다.

JWT 예제

로그인 성공 시 JWT를 저장하고 요청에 포함하는 방식입니다:

// 로그인 시 JWT 저장
localStorage.setItem('token', token);

// 요청에 JWT 포함
const token = localStorage.getItem('token');
fetch('/api/protected', {
  headers: {
    Authorization: `Bearer ${token}`,
  },
});

마무리

React에서 로그인 상태를 관리하는 방법은 애플리케이션의 요구사항과 복잡성에 따라 달라질 수 있습니다. Context API는 간단한 상태 관리에 적합하며, Redux는 더 정교하고 확장 가능한 상태 관리를 제공합니다. 또한, 토큰 저장 위치와 보안 문제를 항상 고려하여 안전하고 효율적인 로그인 상태 관리를 구현해야 합니다.

반응형