Web & App/Frontend Study

React _ react-router-dom의 기능을 활용한 auth 관리

jimmmy_jin 2025. 1. 12. 21:12

React Router를 활용한 사용자 인증 구현

이 글에서는 React Routerfetch API를 이용해 사용자 인증 로직을 구현하는 방법을 설명한다. 로그인(login)과 회원가입(signup) 모드를 처리하며, 서버와의 통신, 인증 토큰 저장, 그리고 만료 시간 관리 등 전체적인 인증 흐름을 다룬다.


코드 구성

작성한 코드는 다음 두 가지 주요 부분으로 나뉜다.

  1. AuthenticationPage 컴포넌트
    사용자에게 로그인/회원가입 폼을 제공한다.
  2. action 함수
    사용자가 입력한 데이터를 처리하고, 서버와 통신하는 역할을 한다.

AuthenticationPage 컴포넌트

import { redirect } from "react-router-dom";
import AuthForm from "../components/AuthForm";

function AuthenticationPage() {
  return <AuthForm />;
}

export default AuthenticationPage;

1. 주요 기능

  • React 컴포넌트
    AuthenticationPage는 AuthForm 컴포넌트를 렌더링한다. AuthForm은 이메일과 비밀번호 입력 필드를 포함한 폼 UI를 제공하며, 제출된 데이터를 action 함수로 넘겨준다.
  • 구조적 역할
    이 컴포넌트는 실제 데이터 처리가 아닌, UI와 로직의 연결점을 제공한다.

action 함수

action 함수는 인증 로직의 핵심이다. 폼 데이터가 제출되면 서버로 요청을 보내고, 응답을 처리하며 인증 상태를 관리한다.

export async function action({ request }) {
  • action 함수는 React Router의 폼 데이터 처리 방식 중 하나다.
  • request 객체를 통해 요청 URL, 쿼리 파라미터, 폼 데이터에 접근한다.

1. URL 파라미터 확인 및 모드 설정

const searchParams = new URL(request.url).searchParams;
const mode = searchParams.get("mode") || "login";
  • URL의 쿼리 파라미터 처리
    searchParams.get("mode")를 통해 요청 URL에서 mode 값을 가져온다.
    • 예: http://localhost:3000/auth?mode=signup → mode는 "signup"으로 설정된다.
  • 기본값 설정
    사용자가 mode를 명시하지 않으면 기본값 "login"을 사용한다. 이를 통해 인증 요청이 로그인인지, 회원가입인지 구분한다.

2. 모드 검증

if (mode !== "login" && mode !== "signup") {
  throw new Response(JSON.stringify({ message: "Invalid request" }), {
    status: 422,
  });
}
  • 유효성 검사
    mode 값이 "login" 또는 "signup"이 아닌 경우 잘못된 요청으로 간주하고 에러를 반환한다.
  • 422 상태 코드
    HTTP 상태 코드 422는 요청 데이터가 잘못되었음을 나타낸다.

3. 폼 데이터 처리

const data = await request.formData();
const authData = {
  email: data.get("email"),
  password: data.get("password"),
};
  • 폼 데이터 추출
    request.formData()를 호출하여 사용자 입력 데이터를 가져온다.
    • data.get("email")은 사용자가 입력한 이메일 값을 가져온다.
    • data.get("password")는 비밀번호 값을 가져온다.
  • 데이터 구조화
    추출한 데이터를 authData 객체로 변환하여 서버로 전송할 준비를 한다.

4. 서버 요청

const response = await fetch(`http://localhost:8080/${mode}`, {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
  },
  body: JSON.stringify(authData),
});
  • fetch API 사용
    서버로 POST 요청을 보낸다.
    mode 값에 따라 서버 경로가 다르다.
    • "login": http://localhost:8080/login
    • "signup": http://localhost:8080/signup
  • 요청 헤더 설정
    Content-Type을 application/json으로 지정하여 요청 본문이 JSON 데이터임을 서버에 알린다.
  • 요청 본문
    authData 객체를 JSON 문자열로 변환하여 서버로 전송한다.

5. 응답 처리

if (response.status === 422 || response.status === 401) {
  return response;
}
  • 422 상태 코드
    데이터가 잘못되었거나 서버에서 요청을 처리할 수 없을 때 반환된다.
    예: 비밀번호가 짧거나 이메일 형식이 잘못된 경우.
  • 401 상태 코드
    인증이 실패했을 때 반환된다. 예를 들어, 로그인 시 잘못된 이메일/비밀번호를 입력한 경우.
if (!response.ok) {
  throw new Response(JSON.stringify({ message: "Something went wrong" }), {
    status: 500,
  });
}
  • 500 상태 코드
    예상치 못한 서버 오류가 발생한 경우 클라이언트에 알려준다.

6. 토큰 저장 및 만료 시간 관리

const resData = await response.json();
const token = resData.token;

localStorage.setItem("token", token);
const expiration = new Date();
expiration.setHours(expiration.getHours() + 1);
localStorage.setItem("expiration", expiration.toISOString());
  • JWT 토큰 처리
    서버로부터 응답을 받아 JSON 데이터를 파싱하고, token 값을 추출한다.
    토큰은 사용자의 인증 상태를 나타내며, 이후 요청에서 권한 확인에 사용된다.
  • Bearer 토큰
    토큰을 사용할 때는 보통 Authorization 헤더에 "Bearer <토큰>" 형식으로 추가된다.
    • "Bearer"는 인증 타입을 나타내며, 서버는 이 토큰을 사용해 사용자를 인증한다.
  • 로컬 저장소 사용
    localStorage에 토큰을 저장하여 브라우저를 닫아도 인증 상태를 유지할 수 있다.
  • 만료 시간 설정
    현재 시간 기준 1시간 뒤 만료 시간을 설정하여 토큰 유효 기간을 관리한다.

7. 성공 시 리다이렉트

return redirect("/");
  • 홈 경로로 리다이렉트
    인증 성공 후 사용자를 루트 경로(/)로 이동시킨다.

 

위 전체 내용에 대한 자세한 코드 참고 링크

: https://github.com/JinLee0811/miniBlog_with_Auth

'Web & App > Frontend Study' 카테고리의 다른 글

React _ Tanstack react Query  (0) 2025.01.13
React _ Tanstack은 무엇일까?  (0) 2025.01.13
React _ loader/라우터 로 에러 핸들링  (1) 2025.01.09
React _ loader 란?  (1) 2025.01.08
React _ 라우팅 및 페이지 #2  (0) 2025.01.07