TIL - 20250907

juni·2025년 9월 6일

TIL

목록 보기
118/316

0907 Full-Stack: JWT 인증과 데이터 흐름 제어 복습


✅ 1. 백엔드(BE): JWT 기반의 안전한 인증 시스템 구축

  • 상태를 유지하지 않는(Stateless) 서버를 위해, JWT(JSON Web Token)를 이용한 인증 및 인가 시스템을 구축했습니다.
  1. 비밀번호 암호화: Spring Security의 PasswordEncoder를 사용하여 사용자의 비밀번호를 단방향 해시(Hash)하여 DB에 저장함으로써, 원본 비밀번호 유출을 원천적으로 방지했습니다.

  2. JWT 발급 및 검증:

    • 로그인 API: 인증 성공 시, 사용자의 식별 정보를 담은 JWT를 생성하여 클라이언트에게 발급합니다.
    • 토큰 검증 필터: 이후 모든 요청에 대해, 클라이언트가 HTTP 헤더에 담아 보낸 JWT를 커스텀 필터가 가로채 유효성을 검증합니다.
  3. 인증 기반 데이터 필터링:

    • 사용자 정보를 기반으로 DB 쿼리(e.g., findAllByUserId(...))를 실행하여, 인가된 데이터만 필터링하여 반환합니다.

✅ 2. 프론트엔드(FE): React Router action을 이용한 데이터 조작

  • loader가 데이터 읽기(Read)를 담당했다면, action 함수는 데이터 생성/수정/삭제(CUD) 작업을 처리하는 React Router의 기능입니다.
  1. 동작 원리:

    • 라우트 설정에 action 함수를 연결하고, React Router의 <Form> 컴포넌트를 사용해 폼을 제출합니다.
    • <Form>은 페이지를 새로고침하는 대신, 연결된 라우트의 action 함수로 요청을 보냅니다.
    • action 함수 내에서 폼 데이터를 추출하여 백엔드 API를 호출하고, 작업이 성공하면 redirect() 함수를 반환하여 사용자를 다른 페이지로 이동시킵니다.
  2. 장점: 데이터 조작 로직을 컴포넌트로부터 완전히 분리하여, 컴포넌트는 UI 렌더링에만 집중할 수 있게 됩니다. 이는 코드의 관심사 분리(SoC) 원칙을 잘 따르는 구조입니다.


✅ 3. 프론트엔드(FE): 인증 상태에 따른 동적 라우팅 및 UI 제어

  • 사용자의 로그인 상태에 따라 페이지 접근을 제어하고, UI를 동적으로 변경하는 로직을 구현했습니다.
  1. loader를 활용한 라우트 가드 (Route Guard):

    • 로그인이 필요한 페이지의 loader 함수에서 브라우저에 저장된 토큰의 유효성을 먼저 확인합니다.
    • 토큰이 없거나 유효하지 않으면, 컴포넌트를 렌더링하는 대신 redirect()를 반환하여 사용자를 로그인 페이지로 강제 이동시킵니다.
  2. 전역 인증 상태 공유:

    • 루트 loader: 최상위 라우트의 loader에서 사용자의 로그인 상태를 확인하고 그 결과를 반환합니다.
    • useRouteLoaderData Hook: 모든 자식 컴포넌트에서 이 Hook을 사용하여 루트 loader의 데이터를 쉽게 조회하고, 로그인 상태에 따라 UI(e.g., 로그인/로그아웃 버튼)를 조건부로 렌더링합니다.
  3. API 호출 리팩토링:

    • 반복적인 fetch 코드를 인증 토큰을 자동으로 헤더에 주입하는 중앙화된 API 유틸리티 함수로 리팩토링했습니다.
    • 이를 통해 컴포넌트에서는 API 호출 로직의 복잡성을 신경 쓸 필요 없이, 직관적으로 함수를 호출할 수 있게 되어 코드의 가독성과 유지보수성이 크게 향상되었습니다.

📌 요약

  • 백엔드JWT토큰 검증 필터를 통해 안전한 Stateless 인증 시스템을 구축하고, 인증 컨텍스트를 활용하여 개인화된 데이터를 제공합니다.
  • 프론트엔드는 데이터 조작을 위해 React Router의 action 함수를 사용하여 컴포넌트와 로직을 분리했습니다.
  • loader라우트 가드로 활용하여 페이지 접근을 제어하고, useRouteLoaderData전역 인증 상태를 공유하며, 중앙화된 API 유틸리티로 코드 품질을 높이는 등 고도화된 아키텍처를 완성했습니다.

0개의 댓글