회원 기능은 모든 서비스의 출발점입니다.
로그인, 회원가입, 비밀번호 변경, 탈퇴 기능 없이 돌아가는 웹 애플리케이션은 상상하기 어렵습니다.
그러나 막상 구현하려 하면 다양한 의사결정이 기다리고 있습니다.
세션을 쓸 것인가, JWT를 쓸 것인가? 비밀번호는 어떤 방식으로 암호화할 것인가?
그리고 무엇보다도, 이 모든 기능을 어떻게 테스트 가능한 구조로 설계할 것인가?
이 글에서는 회원관리 시스템을 구현하는 데 있어 꼭 알아야 할 핵심 요소와 실전 설계 방식을 중심으로 설명합니다.
기초적인 CRUD를 넘어서 보안, 확장성, 유지보수성까지 고려한 구조를 만들어 보고자 합니다.
단순한 기능 구현을 넘어 교육자 관점에서 설계 의도를 함께 짚으며,
수강생 또는 후배 개발자에게도 올바른 기준을 제시할 수 있도록 구성했습니다.
📑 목차
- 회원관리 시스템이 중요한 이유
- 기능 명세 정의
- 도메인 모델 설계
- 회원가입 기능 구현
- 로그인 기능 구현
- 비밀번호 암호화 전략
- 인증 방식 선택 (Session vs JWT)
- 회원정보 수정 및 탈퇴 처리
- 에러 처리 및 검증 로직 구성
- 확장성과 유지보수성을 고려한 설계 팁
- 마무리 및 학습 포인트 정리
- 📌실전 예제 모음
1. 회원관리 시스템이 중요한 이유
회원관리 시스템은 대부분의 웹 애플리케이션에서 가장 기초적이면서도 필수적인 기능입니다. 사용자의 정체성을 확인하고, 그에 따라 접근 권한을 부여하며, 맞춤형 서비스를 제공하기 위해 반드시 필요한 구성 요소입니다. SNS, 커머스, 교육 플랫폼 등 어떤 서비스이든 사용자는 ‘나만의 계정’을 기반으로 시스템과 상호작용합니다.
또한 회원관리 기능은 보안과 밀접하게 연결되어 있습니다. 단순한 회원가입/로그인 기능을 넘어, 비밀번호 암호화, 인증 방식의 선택, 세션 관리, 탈퇴 처리 시 데이터 보존 정책 등 다양한 보안 설계가 동반되어야 합니다. 이 과정에서 기술적인 의사결정뿐 아니라 법적 책임(CCPA, GDPR 등)과 개인정보 보호 원칙까지 고려해야 하므로 단순 기능이 아닌 시스템의 핵심 축이라 할 수 있습니다.
교육자의 입장에서 특히 강조하고 싶은 점은, 이 기능이 초급 개발자에게는 소프트웨어 설계의 출발점이라는 것입니다. 단순히 DB에 유저 정보를 저장하는 수준을 넘어, 레이어 분리, 예외 처리, 유효성 검증, 테스트 코드 작성 등 다양한 개발 원칙을 실천할 수 있는 좋은 연습 무대가 됩니다. 따라서 회원관리는 단순한 기능 구현 단계를 넘어서, 서비스 품질을 좌우하는 기초 체력입니다.
2. 기능 명세 정의
회원관리 시스템을 구현하기 전 가장 먼저 해야 할 일은 기능 명세 정의입니다. 기능 명세서는 단순히 무엇을 만들 것인가를 나열하는 것을 넘어, 각 기능의 흐름, 예외 상황, 입력/출력 조건까지 구체화하는 문서입니다. 명확한 기능 정의는 개발자 간 의사소통을 원활하게 하며, 테스트와 유지보수를 수월하게 만들어 줍니다.
회원관리 시스템에서 일반적으로 요구되는 기능은 다음과 같습니다:
- 회원가입 (유효성 검증, 중복 확인, 비밀번호 암호화)
- 로그인 (인증 토큰 또는 세션 발급)
- 비밀번호 변경 및 초기화
- 회원정보 조회 및 수정
- 회원 탈퇴 처리 및 데이터 정리
여기서 중요한 점은 기능 간의 관계를 고려한 설계입니다. 예를 들어, 로그인을 구현할 때는 인증 방식에 따라 이후 기능에도 영향을 미치며, 탈퇴 처리 방식에 따라 개인정보 보관 정책과의 충돌 여부도 함께 검토해야 합니다.
교육자의 시각에서는 이 단계에서 요구사항 정리 → API 스펙화 → 예외 케이스 설계까지 훈련시키는 것이 매우 중요합니다. 문서화를 통해 학생들이 단순 코딩이 아닌 **기획과 설계의 중요성**을 체험할 수 있도록 도와야 합니다. 실제 프로젝트에서 가장 많은 커뮤니케이션이 발생하는 지점이기도 하며, 협업 능력을 기르는 첫 걸음이 됩니다.
3. 도메인 모델 설계
회원관리 시스템의 기반이 되는 것은 도메인 모델입니다. 도메인 모델은 데이터베이스 테이블 구조뿐 아니라, 객체 지향적으로 시스템을 이해하고 설계하는 출발점이 됩니다. 단순히 User
라는 테이블 하나로 구성할 수도 있지만, 좋은 도메인 설계는 책임과 역할이 분리된 구조로 이어집니다.
예를 들어, 회원 정보를 담당하는 기본 모델은 다음과 같은 속성을 포함할 수 있습니다:
id
: 고유 식별자 (보통 Long 또는 UUID)email
: 로그인용 계정 정보password
: 암호화된 비밀번호nickname
: 사용자 닉네임role
: 사용자 권한 (예: 일반 사용자, 관리자)createdAt
,updatedAt
: 타임스탬프
여기에 더해 UserProfile
, UserSettings
, UserLoginHistory
등 서브 도메인으로 분리하여 관리하면 확장성과 유지보수성이 향상됩니다. 특히 교육 목적에서는 엔티티와 DTO, 서비스 레이어 간의 책임 분리를 학습시키는 데 효과적입니다.
도메인 모델 설계 시 주의할 점은 데이터의 정규화 vs 비정규화, API 응답과의 연관성, 보안 민감 정보의 분리 등 다양한 기준을 고려하는 것입니다. 이를 통해 개발자는 단순히 기능을 만드는 수준을 넘어 비즈니스 로직을 표현하는 모델을 구축하는 역량을 키울 수 있습니다.
4. 회원가입 기능 구현
회원가입은 사용자와 시스템이 처음으로 상호작용하는 매우 중요한 기능입니다. 이 기능에서 사용자 경험이 좋지 않으면 서비스 자체에 대한 신뢰를 잃을 수 있기 때문에, 기능적 완성도와 UX의 정교함이 동시에 요구됩니다.
회원가입 구현은 보통 다음 절차를 포함합니다:
- 입력값 유효성 검증 (프론트 및 백엔드 모두)
- 중복 검사 (이메일, 닉네임 등)
- 비밀번호 암호화 저장 (BCrypt 등 사용)
- DB에 사용자 정보 저장
- (선택) 이메일 인증 또는 본인 확인
이때 가장 중요한 포인트는 비밀번호 암호화 처리입니다. 절대로 평문으로 저장해서는 안 되며, BCryptPasswordEncoder
또는 Argon2
와 같은 안전한 해싱 알고리즘을 사용해야 합니다. 또한, 입력값 검증 로직은 클라이언트에서도 필수이지만, 신뢰할 수 없는 환경이므로 백엔드에서 반드시 이중 검증 이 이뤄져야 합니다.
교육자 입장에서는 이 과정을 통해 단계별 예외 처리와 사용자 친화적 에러 메시지 구성을 지도할 수 있으며, 유닛 테스트 작성을 통해 테스트 주도 개발(TDD)의 기초를 함께 훈련시킬 수 있습니다.
또한 실전 서비스에서는 가입 직후 인증 메일 전송, 자동 로그인 처리, 웰컴 메시지 발송 등 여러 비즈니스 로직이 연결되므로, 비동기 처리나 이벤트 기반 설계까지 함께 고려하는 것이 좋습니다.
5. 로그인 기능 구현
로그인 기능은 사용자가 시스템의 주요 기능을 이용할 수 있도록 인증 토큰 또는 세션을 부여하는 절차입니다. 로그인 과정은 단순해 보일 수 있지만, 실제로는 보안, 성능, 확장성 측면에서 다양한 고려사항이 존재합니다.
일반적인 로그인 절차는 다음과 같습니다:
- 사용자가 이메일과 비밀번호 입력
- 해당 이메일로 등록된 계정 존재 여부 확인
- 입력한 비밀번호와 저장된 해시값 비교
- 성공 시 세션 생성 또는 JWT 토큰 발급
- 로그인 이력 기록 또는 보안 알림 처리
로그인 구현 시 핵심은 암호화된 비밀번호 비교입니다. 이는 단순 문자열 비교가 아닌, BCrypt
기반 해시 비교 함수(예: passwordEncoder.matches()
)를 통해 처리해야 합니다. 또한 로그인 실패 시에는 보안상 유의하여 에러 메시지를 모호하게 제공하는 것이 중요합니다. 예: "아이디 또는 비밀번호가 일치하지 않습니다."
또한 로그인 성공 후 인증 처리 방식(Session 또는 JWT)에 따라 클라이언트의 상태 관리 방식도 달라지므로, 초기 설계 시부터 인증 전략을 명확히 선택해야 합니다. Spring Security를 사용할 경우 UsernamePasswordAuthenticationToken
을 활용한 인증 흐름과 AuthenticationManager
를 통한 인증 위임 구조를 함께 이해하는 것이 좋습니다.
교육자 입장에서 이 기능은 인증 구조를 설명하는 데 핵심이 됩니다. 로그인 성공 시 사용자 정보를 어디에 담아 보낼 것인지, 프론트엔드는 어떻게 토큰을 저장하고 활용할 것인지에 대한 **전체 시스템 흐름의 이해**를 이끌어내야 합니다.
6. 비밀번호 암호화 전략
비밀번호는 사용자 개인정보 중 가장 민감한 정보이며, 보안 설계의 시작점입니다. 비밀번호를 평문으로 저장하는 것은 보안상 치명적인 실수이며, 해커의 공격 대상이 되었을 때 사용자 신뢰와 기업 책임이 모두 무너질 수 있습니다. 따라서 반드시 단방향 해시 알고리즘을 활용한 암호화가 필요합니다.
대표적인 비밀번호 암호화 방식은 다음과 같습니다:
- BCrypt: 가장 널리 사용되며, 솔트(salt)와 라운드를 자동으로 처리.
BCryptPasswordEncoder
제공. - PBKDF2: 반복 키 스트레칭을 지원하는 방식. Java에서
SecretKeyFactory
로 구현 가능. - Argon2: 최신 표준 알고리즘으로 보안성과 속도 측면에서 우수. Spring Security 5 이상에서 지원.
BCrypt는 내부적으로 랜덤 솔트를 자동 적용하기 때문에 동일한 비밀번호라도 매번 다른 해시값이 생성됩니다. 이 점은 무차별 대입 공격에 강한 구조를 형성합니다. 실무에서는 라운드 수를 10 이상으로 설정하는 것이 일반적이며, 보안 정책에 따라 주기적으로 알고리즘을 변경하거나 재해싱 전략을 도입할 수도 있습니다.
교육 현장에서 강조해야 할 점은, 단순히 암호화 라이브러리를 사용하는 것을 넘어서 왜 이 방식이 안전한지, 어떤 공격을 방어할 수 있는지에 대한 이해입니다. 특히 레인보우 테이블, 사전 공격(Dictionary Attack), 브루트 포스에 대한 방어 개념을 실제 예시와 함께 설명하면 학습 효과가 높습니다.
또한 개발자는 비밀번호 변경/재설정 시에도 같은 암호화 전략을 일관성 있게 적용하고, 인증 실패 횟수 제한, 캡차 적용 등의 보안 강화 요소도 함께 설계해야 합니다.
7. 인증 방식 선택 (Session vs JWT)
회원 인증 방식은 시스템의 보안 구조와 사용자 경험에 중대한 영향을 미칩니다. Spring 기반 애플리케이션에서는 세션(Session) 기반 인증과 JWT(Json Web Token) 기반 인증이 대표적이며, 각각의 방식은 장단점이 분명하게 존재합니다.
세션 기반 인증
서버가 클라이언트 로그인 요청을 처리한 뒤 세션 ID를 생성하고, 이를 클라이언트의 쿠키에 저장합니다. 서버는 이 세션 ID를 메모리 또는 외부 저장소(Redis 등)에 유지하여, 요청마다 세션을 조회해 인증을 처리합니다.
장점: 서버에서 세션 상태를 관리하기 때문에 토큰 변조에 대한 방어가 쉬움. 단점: 상태를 서버가 유지하므로 확장성이 떨어지고, 분산 서버 환경에서 세션 동기화가 필요함.
JWT 기반 인증
로그인 시 서버가 JWT를 발급하고, 클라이언트는 이를 Authorization
헤더에 담아 요청합니다. 서버는 해당 토큰을 복호화하여 사용자 정보를 검증합니다.
장점: 서버가 상태를 저장하지 않으므로 무상태(stateless) 환경에 적합하며, 마이크로서비스 아키텍처에서 효율적임. 단점: 토큰이 클라이언트에 저장되기 때문에 노출 시 위험하며, 토큰 만료 전에는 서버 측에서 강제 만료시키기 어렵다는 단점이 있음.
교육적 관점에서 가장 중요한 것은 "우리 서비스의 구조와 목적에 맞는 인증 방식을 설계하라"는 원칙을 학습시키는 것입니다. 예를 들어, 학습용 단일 서버라면 세션 기반으로 충분하지만, 프론트/백엔드 분리 구조나 모바일 연동이 필요한 서비스라면 JWT 기반이 더 적합할 수 있습니다.
Spring Security에서는 SessionAuthenticationStrategy
및 JwtAuthenticationFilter
등 다양한 인증 컴포넌트를 제공하므로, 학습자가 구조를 이해하고 커스터마이징하는 연습을 병행하는 것이 좋습니다.
8. 회원정보 수정 및 탈퇴 처리
회원관리 시스템의 완성도를 결정짓는 요소 중 하나가 바로 회원정보 수정 및 탈퇴 처리입니다. 많은 개발자들이 로그인과 회원가입에 집중한 나머지, 이 기능들을 단순한 CRUD로만 처리하지만, 실제 서비스에서는 데이터 정합성, 보안, 정책 준수까지 고려해야 합니다.
회원정보 수정
회원정보 수정 기능은 일반적으로 닉네임, 프로필 이미지, 연락처, 비밀번호 변경 등을 포함합니다. 이때 중요한 점은 수정 가능 항목에 대한 명확한 제한과 비밀번호 변경 시 재인증입니다. 또한 민감한 정보(이메일, 휴대전화 등)를 변경할 경우 추가 인증 절차를 요구하는 것이 바람직하며, 변경 로그 기록 역시 보안 감사 측면에서 필요합니다.
회원 탈퇴 처리
회원 탈퇴는 단순히 계정을 삭제하는 것 이상의 의미를 가집니다. 실제 서비스에서는 다음 두 가지 방식이 있습니다:
- 물리적 삭제(Physical Delete): DB에서 사용자 데이터를 완전히 제거. 단점은 되돌릴 수 없고, 연관 데이터에 오류가 발생할 수 있음.
- 논리적 삭제(Logical Delete):
is_active
또는deleted_at
필드 등을 활용하여 탈퇴 여부만 표시. 복구 가능하고 감사 목적의 기록 유지에 유리함.
실제 운영 서비스에서는 대부분 논리적 삭제를 채택하며, GDPR 등 개인정보 보호법을 준수하여 유효기간이 지난 정보는 주기적으로 완전 삭제해야 합니다. 또한 탈퇴 시 사용자의 연관 정보 처리(예: 작성 글, 댓글, 결제 기록 등)도 설계 단계에서 반드시 고려해야 합니다.
교육 현장에서는 이 기능을 통해 소프트 삭제의 개념, DB 상태 관리 전략, 보안 감수성을 동시에 가르칠 수 있습니다. 실제 운영 환경을 모사하여, 탈퇴 후 재가입 시 기존 데이터가 어떻게 처리되는지, 복구 가능성은 있는지 등을 시나리오 기반으로 토론하게 하면 큰 학습 효과를 얻을 수 있습니다.
9. 에러 처리 및 검증 로직 구성
회원관리 시스템에서 에러 처리와 입력값 검증은 단순한 유효성 검사 이상의 의미를 가집니다. 이 기능들은 시스템 안정성 확보, 보안 위험 차단, 사용자 경험 개선에 직접적인 영향을 미치며, 특히 다수의 외부 입력을 수용하는 회원 기능에서는 반드시 정교하게 구성되어야 합니다.
입력값 검증
Spring 환경에서는 @Valid
또는 @Validated
애노테이션을 활용한 Bean Validation이 대표적이며, DTO에 @NotBlank
, @Email
, @Size
등 다양한 제약 조건을 선언할 수 있습니다. 검증 실패 시 MethodArgumentNotValidException
이 발생하고, 이를 전역 @RestControllerAdvice
에서 처리하는 방식이 권장됩니다.
또한 도메인 고유 규칙(예: 특정 이메일 도메인만 허용, 비밀번호 복잡도 기준 등)은 커스텀 검증 로직으로 별도 구현하는 것이 바람직합니다. 프론트엔드와 백엔드에서 이중 검증을 통해 잘못된 접근을 방지하며, 백엔드 검증 결과는 사용자가 이해할 수 있는 형태로 메시지를 반환해야 합니다.
에러 처리
에러 처리의 핵심은 일관성과 가독성입니다. Spring에서는 @RestControllerAdvice
와 @ExceptionHandler
조합으로 전역 예외를 관리하며, 다음과 같은 구조를 권장합니다:
{
"timestamp": "2025-05-17T12:00:00",
"status": 400,
"error": "Bad Request",
"message": "이미 등록된 이메일입니다.",
"code": "USER_DUPLICATED"
}
위와 같이 에러 코드, 사용자 메시지, HTTP 상태코드를 구분하면 클라이언트 측에서도 효율적으로 처리할 수 있습니다. 또한 보안상 민감한 내부 예외(NullPointerException
등)는 그대로 노출하지 않도록 래핑하거나 로깅 처리만 하도록 해야 합니다.
교육 관점에서는 이 항목이 예외 설계, 레이어 분리, 응답 구조화를 통합적으로 훈련할 수 있는 좋은 기회입니다. 수강생이 실제 서비스 수준의 오류 응답 구조를 설계하고, 테스트 케이스를 통해 예외 흐름을 점검하게 함으로써 품질 높은 백엔드 개발 습관을 길러줄 수 있습니다.
10. 확장성과 유지보수성을 고려한 설계 팁
회원관리 시스템은 단순히 작동만 하는 구조로 설계해서는 안 됩니다. 시간이 지날수록 요구사항은 변하고, 연계 시스템은 복잡해지며, 코드베이스는 점점 무거워집니다. 따라서 초기에 확장성과 유지보수성을 고려한 설계가 반드시 필요합니다. 특히 교육자 관점에서는 이러한 장기적 사고를 학습자에게 꾸준히 주입해야 합니다.
1. 계층 분리와 책임 분산
도메인 로직, 서비스 로직, 컨트롤러 로직을 명확히 구분하고, DTO
, Entity
, Repository
, Service
계층 간 역할을 엄격히 분리합니다. 이렇게 하면 각 계층에 변경이 생겨도 영향 범위를 최소화할 수 있습니다.
2. 이벤트 기반 확장
회원가입 시 이메일 전송, 포인트 지급, 관리자 알림 등 다양한 후처리가 필요한 경우가 많습니다. 이 로직들을 모두 서비스 메서드 내부에 넣으면 코드가 복잡해지고 테스트도 어려워집니다. Spring의 이벤트 발행 구조(ApplicationEventPublisher) 또는 비동기 메시징(RabbitMQ, Kafka 등)을 통해 후처리 로직을 분리하는 것이 바람직합니다.
3. 인증 방식 분리 및 재사용 구조화
세션 기반과 JWT 기반 인증을 모두 지원해야 하는 상황이 발생할 수 있으며, OAuth2 로그인과 같은 기능이 추가될 수 있습니다. 이를 고려하여 인증 관련 컴포넌트를 별도 모듈 또는 패키지로 분리하면 확장에 유리합니다. 또한 필터, 인터셉터, 토큰 처리 로직을 공통 모듈화하여 중복을 줄이는 것이 핵심입니다.
4. 환경 설정 분리 및 지속적 리팩토링
API 응답 포맷, 인증 토큰 설정, 에러 메시지 등은 환경에 따라 변경될 수 있으므로 application.yml 또는 Config 클래스에 위임하여 유연하게 관리합니다. 또한 비즈니스 로직이 복잡해질 경우 도메인 서비스, 헬퍼 클래스, 유틸성 모듈을 적절히 나누어 **읽기 쉽고 테스트 가능한 코드**로 유지하는 것이 중요합니다.
이러한 전략은 단기적인 구현 속도보다 장기적인 유지보수성과 팀 협업 효율을 보장합니다. 강의나 프로젝트에서 초기 설계 구조를 학습자와 함께 고민하는 시간을 반드시 확보하여, 기능 중심 사고에서 아키텍처 중심 사고로 전환할 수 있도록 지도해야 합니다.
11. 마무리 및 학습 포인트 정리
회원관리 시스템은 단순한 사용자 CRUD 기능을 넘어서, 웹 서비스의 보안, 확장성, 유지보수성 전반을 설계하고 구현하는 종합적인 과제입니다. 이번 장에서는 기능 명세부터 도메인 설계, 인증 방식, 암호화, 예외 처리, 유지보수 전략까지 다양한 측면을 다루었습니다.
특히 교육 현장에서 이 주제를 다룰 때는 단순 기능 구현에 그치지 않고, 다음과 같은 학습 포인트를 강조해야 합니다:
- 요구사항 정의 → 기능 설계 → 구조 설계의 흐름을 경험적으로 익힐 것
- 보안 사고 예방을 위한 인증, 암호화, 예외 처리의 중요성을 인지할 것
- 서비스 확장과 협업을 고려한 코드 모듈화, 책임 분리, 테스트 전략을 설계할 것
- 기술 선택(Session vs JWT, BCrypt vs Argon2 등)에 대한 근거 있는 의사결정 훈련
실무에서도 회원 기능은 프로젝트 초기 단계에 구현되며, 이후 모든 기능과 연결되므로 처음부터 탄탄하게 설계하는 것이 중요합니다. 로그인 한 사용자만 접근 가능한 기능이 있는 경우, 인증 실패 시 사용자 경험을 어떻게 처리할 것인지도 함께 고려해야 합니다. 또한 리팩토링이 쉬운 구조를 초기에 설계해두면, 서비스 규모가 커졌을 때도 부담 없이 유지보수할 수 있습니다.
마지막으로, 교육자의 역할은 기술을 알려주는 것을 넘어 어떻게 설계하고, 왜 그런 구조가 필요한지 사고하게 만드는 것입니다. 회원관리 시스템은 그 출발점으로 가장 적합한 주제이며, 이 장을 통해 학습자들이 실무 감각과 설계 사고력을 함께 키울 수 있기를 바랍니다.
📌 실전 예제 모음
1. 회원가입 요청 DTO
public class SignupRequest {
@NotBlank(message = "이메일은 필수입니다.")
@Email(message = "이메일 형식이 아닙니다.")
private String email;
@NotBlank(message = "비밀번호는 필수입니다.")
@Size(min = 8, message = "비밀번호는 8자 이상이어야 합니다.")
private String password;
@NotBlank(message = "닉네임은 필수입니다.")
private String nickname;
}
2. 비밀번호 암호화 및 회원 저장 로직
public User register(SignupRequest request) {
String encryptedPassword = passwordEncoder.encode(request.getPassword());
User user = new User(
request.getEmail(),
encryptedPassword,
request.getNickname()
);
return userRepository.save(user);
}
3. 로그인 API 컨트롤러 예제
@PostMapping("/api/v1/auth/login")
public ResponseEntity<?> login(@RequestBody LoginRequest request) {
User user = userService.findByEmail(request.getEmail());
if (!passwordEncoder.matches(request.getPassword(), user.getPassword())) {
throw new InvalidCredentialsException();
}
String token = jwtTokenProvider.createToken(user.getId(), user.getRole());
return ResponseEntity.ok(new LoginResponse(token));
}
4. 전역 예외 처리 핸들러
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<?> handleValidation(MethodArgumentNotValidException ex) {
String message = ex.getBindingResult()
.getAllErrors()
.get(0)
.getDefaultMessage();
return ResponseEntity.badRequest().body(Map.of("error", message));
}
@ExceptionHandler(InvalidCredentialsException.class)
public ResponseEntity<?> handleInvalidCredentials() {
return ResponseEntity.status(HttpStatus.UNAUTHORIZED)
.body(Map.of("error", "이메일 또는 비밀번호가 올바르지 않습니다."));
}
}
5. 회원 탈퇴 시 소프트 삭제 처리
@Transactional
public void withdraw(Long userId) {
User user = userRepository.findById(userId)
.orElseThrow(() -> new NotFoundException("사용자를 찾을 수 없습니다."));
user.deactivate(); // isActive 필드 false 처리
}
'프로그래밍 > 자바[JAVA]' 카테고리의 다른 글
27장. MVC 패턴 도입 실습 (0) | 2025.05.18 |
---|---|
26장. 텍스트 파일 기반 데이터 저장 (0) | 2025.05.17 |
24장. 자바로 배우는 CRUD 게시판 만들기 (1) | 2025.05.17 |
23장. 스트림(Stream) API 기초 - 자바의 선언형 데이터 처리 시작하기 (3) | 2025.05.17 |
22장. 파일 입출력 완전 정복 - File, BufferedReader, BufferedWriter 활용법 (0) | 2025.05.16 |