Django와 React를 연동하여 로그인 후 사용자 권한에 따라 화면을 다르게 보여주는 방법
초보자도 이해하기 쉽게 단계별로 정리했습니다.
Django에서 사용자가 로그인하면, 로그인 성공 시 사용자 정보를 반환하도록 설정합니다. 이를 위해 CustomLoginView를 수정합니다.
1-1. CustomLoginView 설정
사용자가 로그인하면 사용자 정보와 토큰(Access Token, Refresh Token)을 반환합니다.
from rest_framework.response import Response
from rest_framework.permissions import AllowAny
from rest_framework_simplejwt.tokens import RefreshToken
from dj_rest_auth.views import LoginView
class CustomLoginView(LoginView):
permission_classes = [AllowAny] # 모든 사용자 접근 허용
def post(self, request, *args, **kwargs):
# 기존 로그인 로직 실행
response = super().post(request, *args, **kwargs)
# 로그인한 사용자 정보 가져오기
user = self.request.user
refresh = RefreshToken.for_user(user)
# 사용자 정보를 응답 데이터에 포함
data = {
"username": user.username,
"email": user.email,
"is_admin": user.is_staff, # 관리자인지 여부
"tokens": {
"refresh": str(refresh),
"access": str(refresh.access_token),
},
}
return Response(data)
이제 Django는 로그인 성공 시 사용자 정보를 JSON으로 반환합니다.
React에서 Django의 CustomLoginView를 호출하여 로그인 요청을 보내고, 반환된 사용자 정보를 저장합니다.
2-1. 로그인 API 요청 함수
axios를 사용하여 Django 로그인 API에 요청을 보냅니다.
import axios from "axios";
export const loginUser = async (credentials) => {
try {
const response = await axios.post(${API_URL}/login/, credentials, {
headers: {
"Content-Type": "application/json",
},
withCredentials: true, // 쿠키 인증 포함
});
return response.data; // Django에서 반환된 사용자 정보
} catch (error) {
console.error("Login error:", error);
throw error;
}
};
2-2. React에서 로그인 상태 관리
React Context를 사용해 로그인한 사용자 정보를 저장하고 관리합니다.
import React, { createContext, useState, useContext } from "react";
import { loginUser } from "./api/loginApi";
const AuthContext = createContext();
export const AuthProvider = ({ children }) => {
const [user, setUser] = useState(null);
const login = async (credentials) => {
try {
const userData = await loginUser(credentials);
setUser(userData); // 사용자 정보를 상태에 저장
} catch (error) {
console.error("Login failed:", error);
}
};
const logout = () => {
setUser(null); // 로그아웃 시 사용자 정보 초기화
};
return (
<AuthContext.Provider value={{ user, login, logout }}>
{children}
</AuthContext.Provider>
);
};
export const useAuth = () => useContext(AuthContext);
3-1. ProtectedRoute 컴포넌트
특정 페이지를 사용자 권한에 따라 보호합니다. 예를 들어, 관리자인 경우에만 접근 가능하도록 설정합니다.
import React from "react";
import { Navigate } from "react-router-dom";
import { useAuth } from "./AuthContext";
const ProtectedRoute = ({ children, adminOnly }) => {
const { user } = useAuth();
// 비로그인 사용자는 로그인 페이지로 이동
if (!user) {
return ;
}
// 관리자가 아닌 사용자가 관리자 페이지에 접근하면 리디렉션
if (adminOnly && !user.is_admin) {
return ;
}
return children;
};
export default ProtectedRoute;
React Router를 사용해 권한 기반 경로를 설정합니다.
import React from "react";
import { BrowserRouter as Router, Route, Routes } from "react-router-dom";
import { AuthProvider } from "./AuthContext";
import ProtectedRoute from "./ProtectedRoute";
import LoginPage from "./components/LoginPage";
import AdminDashboard from "./components/AdminDashboard";
import UserDashboard from "./components/UserDashboard";
import Unauthorized from "./components/Unauthorized";
const App = () => (
{/ 로그인 페이지 /}
<Route path="/login" element={} />
{/* 일반 사용자 대시보드 */}
<Route
path="/dashboard"
element={
<ProtectedRoute>
<UserDashboard />
</ProtectedRoute>
}
/>
{/* 관리자 대시보드 */}
<Route
path="/admin"
element={
<ProtectedRoute adminOnly>
<AdminDashboard />
</ProtectedRoute>
}
/>
{/* 권한 없음 페이지 */}
<Route path="/unauthorized" element={<Unauthorized />} />
</Routes>
</AuthProvider>
);
export default App;
권한에 따라 화면 보호 및 이동:
1. 관리자 계정:
• /admin 경로 접근 가능
• /dashboard 경로 접근 가능
2. 일반 사용자 계정:
• /dashboard 경로 접근 가능
• /admin 경로 접근 시 /unauthorized로 리디렉션
3. 비로그인 사용자:
• /login 경로로 리디렉션
이 가이드를 따르면 Django와 React를 연동해 권한 기반 컴포넌트 렌더링을 구현할 수 있습니다. 😊