leebaek

[React] JWT 기반 로그인 구현하기 - 1편 본문

웹/React

[React] JWT 기반 로그인 구현하기 - 1편

leebaek 2025. 5. 24. 17:35

 

■ JWT란

■ accessToken과 refreshToken

■ zustand를 이용한 fetch 기반 로그인 처리

■ 로그인폼 구현


 

안녕하세요. 오늘은 JWT기반 로그인 구현 방법에 대해 정리해보겠습니다.

( 로그아웃은 다음 포스팅에서 다룰 예정 ~ )

Zustand로 전역상태를 관리하고, sessionStorage에 토큰 저장, 그리고 Spring 백엔드 API와 연동합니다 :)

 

 


■ JWT란

: 인증된 사용자인지를 증명하는 암호화된 토큰

- 서버가 발급하고, 클라이언트는 이를 저장해 요청할 때마다 보내 인증을 유지함


■ accessToken과 refreshToken

종류 설명 유효기간
Access Token 인증된 사용자임을 증명 보통 짧게 ( 예: 15분 )
Refresh Token Access Token 재발급용 길게 ( 예: 2주 )

 


■ zustand를 이용한 fetch 기반 로그인 처리

1️⃣ 단계 : 스토어 생성

import { create } from 'zustand';

export const useAuthStore = create((set) => ({
  token: null,
  login: async (email, password) => { /* 아래에서 설명 */ },
  logout: () => { /* 다음포스팅에서 다룰 예정 */ }
}));

 

- create 함수로 Zustand 스토어를 생성

- 초기 상태 token은 null

- 상태 변경 함수 login, logout


2️⃣ 단계 : login 함수 구현

login: async (email, password) => {
  try {
    const res = await fetch('/api/login', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ email, password }),
    });

    if (!res.ok) throw new Error('로그인 실패');

    const data = await res.json();
    const accessToken = data.accessToken;

    sessionStorage.setItem('accessToken', accessToken);
    set({ token: accessToken });

    window.location.href = '/dashboard';
  } catch (err) {
    alert(err.message);
  }
}

 

- fetch로 /api/login에 로그인 정보 전송 ( 이메일, 비밀번호 )

- 응답이 실패하면 에러 발생

- *응답에서 accessToken 추출*

- sessionStorage에 저장 -> 새로고침 해도 로그인 유지됨

- Zustand의 token 상태 변경

- 로그인 성공 시 대시보드로 이동


■ 로그인폼 구현

로그인 폼은 useState 사용해서 간단하게 코드 구현해봤습니다~~!

import { useState } from 'react';
import { useAuthStore } from '../store/authStore';

const LoginForm = () => {
  const [email, setEmail] = useState('');
  const [pw, setPw] = useState('');
  const login = useAuthStore(state => state.login);

  const handleLogin = async () => {
    await login(email, pw);
  };

  return (
    <>
      <input value={email} onChange={e => setEmail(e.target.value)} />
      <input type="password" value={pw} onChange={e => setPw(e.target.value)} />
      <button onClick={handleLogin}>로그인</button>
    </>
  );
};

 

다음 포스팅에선 accessToken과 HttpOnly 쿠키를 전송하는 로그아웃 기능 구현에 대해 소개해볼게요~