TIL - 20250807

juni·2025년 8월 7일

TIL

목록 보기
87/317

0807 JWT 인증 및 프론트엔드 모듈화


✅ JWT 기반 인증 시스템 구현

  • Stateless(무상태) 인증을 위해 JWT(JSON Web Token)를 도입했습니다. JWT는 인증에 필요한 정보들을 암호화된 JSON 형태로 담고 있어, 서버는 토큰 검증만으로 사용자를 인증할 수 있습니다.

➕ JWT 구성 요소 및 구현 클래스

  • JWT의 구조:

    • Header: 토큰의 타입(JWT)과 사용하는 해시 알고리즘(e.g., HS256) 정보를 담습니다.
    • Payload: 사용자의 ID, 권한(role) 등 실제 전달할 데이터(Claim)를 담습니다. 만료 시간(exp) 등을 설정할 수 있습니다.
    • Signature: Header와 Payload를 비밀 키(Secret Key)로 서명한 값으로, 토큰의 위변조 여부를 검증하는 데 사용됩니다.
  • 구현 클래스 및 설정:

    • JwtProvider: JWT의 생성(create), 유효성 검증(validate), 정보 추출(parse)을 담당하는 핵심 클래스입니다.
    • JwtProperties: application.yml에 정의된 JWT 관련 설정(비밀 키, 만료 시간 등)을 객체로 바인딩하여 관리하는 클래스입니다. (@ConfigurationProperties)
    • build.gradle: JWT 라이브러리(io.jsonwebtoken:jjwt-api, jjwt-impl, jjwt-jackson) 의존성을 추가했습니다.
    • application.yml: 외부에 노출되면 안 되는 JWT 비밀 키와 토큰 만료 시간을 설정했습니다.

✅ 로그인 API 응답 변경 및 페이지 뷰 구현

  • 로그인 성공 시, 기존의 단순 성공 메시지 대신 인증을 위한 JWT 토큰을 클라이언트에게 반환하도록 로직을 수정했습니다.
  1. AuthResponse (DTO): 로그인 성공 시 클라이언트에게 전달할 응답 데이터를 담는 DTO입니다. 생성된 accessToken을 포함합니다.
  2. UserService & AuthController 수정:
    • UserServiceauthenticate 메서드는 인증 성공 후 사용자 정보를 반환합니다.
    • AuthController는 반환된 사용자 정보를 기반으로 JwtProvider를 통해 JWT를 생성하고, 이를 AuthResponse에 담아 클라이언트에게 전달합니다.
  3. PageController 및 뷰 파일 추가:
    • 서버에서 직접 HTML 페이지를 렌더링하기 위해 PageController를 추가했습니다.
    • /, /login, /signup 등의 경로 요청 시 각각 index.html, login.html, signup.html을 반환하도록 매핑했습니다.

✅ 프론트엔드 JavaScript 모듈화 및 동적 로딩

  • JavaScript 코드의 재사용성과 유지보수성을 높이기 위해 ES6 모듈 시스템을 도입했습니다. 이를 통해 기능별로 파일을 분리하고 import/export 구문을 사용하여 의존성을 관리합니다.

  • type="module": <script> 태그에 type="module" 속성을 추가하여 브라우저가 해당 파일을 모듈로 인식하게 했습니다.

  • 페이지별 동적 로딩(Dynamic Import):

    • App.js: 모든 페이지의 진입점 역할을 하는 메인 스크립트입니다. 현재 페이지의 URL을 확인하여 해당 페이지에 필요한 JS 모듈만 동적으로 불러옵니다.
    • import() 함수: import()는 Promise를 반환하는 함수로, 필요할 때 모듈을 비동기적으로 로드합니다. 이를 통해 초기 페이지 로딩 시 모든 JS를 한 번에 불러오지 않고, 필요한 모듈만 가져와 초기 로딩 성능을 최적화할 수 있습니다. (코드 스플리팅)
// App.js 예시
document.addEventListener('DOMContentLoaded', () => {
    const page = getCurrentPage(); // 현재 페이지 식별 (e.g., 'signup')

    // 동적 import를 사용하여 페이지에 맞는 모듈 로드
    import(`./pages/${page}.js`)
        .then(module => {
            if (module.init) {
                module.init(); // 모듈의 초기화 함수 실행
            }
        })
        .catch(err => console.error(`${page}.js 로드 실패:`, err));
});

0개의 댓글