[유신사 프로젝트] 로그인 & 회원가입 기능 1

2025. 9. 11. 00:56프로젝트

최근 직장을 다니면서 개인 공부를 소홀히 하는 것 같아, 공부도 하고 실습도 할 겸 아는 학교 동생들과 함께 작은 프로젝트를 기획하게 되었다. 개인 프로젝트라서 거창한 목표를 세운 건 아니지만, 각자에게 도움이 될 만한 내용들을 공부하고 이를 블로그에 기록해 나가기로 했다.

 

이번 프로젝트의 개발 환경은 Spring Boot + JPA + React(SPA) 조합이고, 장기적으로는 확장성을 고려해 MSA 구조까지 염두에 두고 있다.


1. 로그인

1-1. JWT 로그인 방식

먼저 로그인 방식은 여러 가지가 있었지만, 우리는 JWT 기반 방식을 채택했다.
오늘은 JWT가 어떤 방식인지 간단히 소개하고, 구체적인 다루는 방법은 별도의 글에서 정리할 예정이다.

 

채택 이유
우리 프로젝트는 SPA와 MSA 구조를 고려하고 있기 때문에, 서버가 상태를 직접 관리하지 않는 것이 더 유리하다. JWT는 서버가 따로 세션 저장소를 두지 않고도 인증을 처리할 수 있어서 확장성과 성능 측면에서 적합하다고 판단했다.

 

구조

  1. 클라이언트가 아이디/비밀번호를 입력
  2. 서버가 검증 후 JWT 토큰 발급
  3. JWT는 Header.Payload.Signature 구조로 되어 있으며,
  4. 클라이언트는 이후 요청마다 토큰을 함께 보내고 서버는 이를 검증해 인증 처리한다.

장점

  • 서버가 stateless 하게 동작 (세션 저장 불필요)
  • MSA, SPA 환경에 최적화
  • 확장성과 성능 면에서 유리

단점

  • 토큰 크기가 커서 요청마다 오버헤드 발생 가능
  • 토큰 탈취 시 만료 전까지 위험 (→ Refresh Token 같은 보완책 필요)

1-2. 세션 기반 로그인

비교를 위해 세션 기반 로그인도 정리해 보았다.

 

구조

  1. 로그인 성공 시 서버에서 세션 ID 생성 → 메모리나 DB에 저장
  2. 클라이언트는 세션ID를 쿠키에 담아 요청마다 전송
  3. 서버는 세션ID를 확인해 유저 상태를 관리

장점

  • 구현이 상대적으로 단순
  • 세션 만료, 강제 로그아웃 처리 용이

단점

  • 서버가 stateful 하게 동작해야 함
  • 서버 확장 시 세션 동기화 문제 발생 (→ Redis 같은 분산 세션 필요)

2. 회원가입

2-1. 유저 정보 저장 방식

회원가입에서는 유저 정보를 어떻게 안전하게 저장할지가 핵심이다.

 

비밀번호 관리

  • 절대 평문 저장 ❌
  • BCrypt 기반 해시 + 솔트 처리
  • 로그인 시 passwordEncoder.matches(rawPassword, passwordHash)로 검증

2-2. 예시

  • BCryptPasswordEncoder Bean 등록
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration
public class SecurityConfig {

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder(); // strength(강도) 기본값 10
    }
}

 

  • 회원가입 시 비밀번호 해싱 후 저장
import lombok.RequiredArgsConstructor;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
public class UserService {

    private final UserRepository userRepository;
    private final PasswordEncoder passwordEncoder;

    public void registerUser(UserRegisterRequest request) {
        String encodedPassword = passwordEncoder.encode(request.getPassword());

        User user = User.builder()
                .userId(request.getUserId())
                .email(request.getEmail())
                .passwordHash(encodedPassword) // 해싱된 비밀번호 저장
                .userType(UserType.USER)
                .build();

        userRepository.save(user);
    }
}

 

  • 로그인 시 비밀번호 검증
import lombok.RequiredArgsConstructor;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
public class AuthService {

    private final UserRepository userRepository;
    private final PasswordEncoder passwordEncoder;

    public boolean login(String userId, String rawPassword) {
        User user = userRepository.findByUserId(userId)
                .orElseThrow(() -> new IllegalArgumentException("존재하지 않는 회원입니다."));

        // 입력받은 비밀번호(raw)와 저장된 비밀번호(hash) 비교
        if (passwordEncoder.matches(rawPassword, user.getPasswordHash())) {
            // 검증 성공 → JWT 발급 로직으로 연결
            return true;
        } else {
            throw new IllegalArgumentException("비밀번호가 일치하지 않습니다.");
        }
    }
}

 

핵심은 encode()로 저장하고, matches()로 비교하는 구조다.


2-3. 유저 CRUD

Create (회원가입)

  • UserService.createUser(UserRegisterRequest request)
  • 요청 받은 데이터를 엔티티로 변환 후 저장
  • 비밀번호는 반드시 해싱 처리

Read (회원 조회)

  • UserService.getUser(UUID id or String userId)
  • 특정 유저 혹은 전체 유저 조회 가능

Update (회원 정보 수정)

  • 닉네임, 이메일, 비밀번호 변경 등
  • 비밀번호 변경 시 다시 해시 처리 필수

Delete (회원 탈퇴)

  • 실제 삭제 대신 status = DELETED로 소프트 딜리트 처리
  • 추후 복구나 데이터 추적 가능

정리

  • 로그인은 JWT 기반을 채택 → MSA/SPA 환경에서 적합하고 서버 확장에 유리
  • 세션 방식은 단순하지만 확장성에 불리 → 프로젝트 성격에 맞게 선택
  • 회원가입은 유저 엔티티 설계 + 안전한 비밀번호 저장이 핵심
  • CRUD 기능으로 기본적인 유저 관리 구조 마련

'프로젝트' 카테고리의 다른 글

[유신사 프로젝트] 상품 1  (0) 2025.11.16
[유신사 프로젝트] 로그인 & 회원가입 기능 2  (0) 2025.09.21
보물찾기 게임  (0) 2025.03.26