Spring Boot 기반의 백엔드 API 서버입니다.
- JWT 토큰 기반 인증 시스템
- 사용자 관리 (회원가입, 로그인, 프로필 관리)
- 소셜 로그인 지원 (카카오, 구글)
- RESTful API
- 글로벌 예외 처리 시스템
- Spring Boot 3.5.3
- JDK 21
- Spring Security
- Spring Data JPA
- JWT (JSON Web Token)
- Spring OAuth2
- PostgreSQL
- Gradle
- Lombok
src/main/java/org/example/vibelist/
├── global/
│ ├── auth/ # 인증 관련 (JWT, OAuth2)
│ ├── config/ # 보안 설정
│ ├── constants/ # 상수 정의
│ ├── exception/ # 글로벌 예외 처리
│ ├── jpa/ # JPA 기본 엔티티
│ ├── oauth2/ # OAuth2 설정
│ ├── security/ # 보안 관련
│ ├── user/ # 사용자 관리
│ └── util/ # 유틸리티
└── VibeListApplication.java
- Access Token: API 요청 시 사용 (1시간 유효) - 메모리에서만 관리
- Refresh Token: Access Token 갱신 시 사용 (24시간 유효) - 데이터베이스에 암호화 저장
- Access Token: 데이터베이스에 저장하지 않고 메모리에서만 관리하여 보안 강화
- Refresh Token: 데이터베이스에 암호화하여 저장하여 장기간 인증 관리
- 소셜 로그인의 경우에도 동일한 정책 적용
- 프론트엔드: 카카오/구글 OAuth 인가 코드 → 백엔드 /v1/auth/{provider} 전달
- 백엔드 처리 과정:
- 인가 코드 → SNS Access Token 발급
- provider_user_id로 user_social 조회 → 없으면 신규 가입
- user 레코드 + 랜덤 username 생성 (iu_8347 등)
- user_profile insert (이메일·닉네임 등)
- user_social insert
- JWT Access/Refresh 발급
- 프론트엔드: Access Token 헤더 보관, Refresh Token은 쿠키 자동 저장
- User: 사용자 기본 정보 (username, password, role)
- UserProfile: 사용자 프로필 정보 (email, name, phone, avatarUrl, bio)
- UserSocial: 소셜 계정 연동 정보 (provider, providerUserId, providerEmail)
- User ↔ UserProfile: 1:1 관계 (ID 공유)
- User ↔ UserSocial: 1:N 관계 (소셜 계정 다중 연동 가능)
POST /v1/auth/signup- 회원가입POST /v1/auth/login- 로그인POST /v1/auth/refresh- 토큰 갱신POST /v1/auth/kakao- 카카오 소셜 로그인 (인가 코드 기반)POST /v1/auth/google- 구글 소셜 로그인 (인가 코드 기반)POST /v1/auth/social/login- 소셜 로그인 (기존 방식)
POST /v1/users- 사용자 생성GET /v1/users/me- 현재 사용자 정보 조회PUT /v1/users/me- 현재 사용자 프로필 업데이트DELETE /v1/users/me- 현재 사용자 삭제GET /v1/users/search- 사용자 검색 (이름 기반)
GET /v1/users- 모든 사용자 조회GET /v1/users/{userId}- 특정 사용자 조회PUT /v1/users/{userId}/profile- 특정 사용자 프로필 업데이트DELETE /v1/users/{userId}- 특정 사용자 삭제
jwt.secret=your-secret-key-here-make-it-long-and-secure-for-production
jwt.access-token-validity=3600000
jwt.refresh-token-validity=86400000oauth.kakao.client-id=your-kakao-client-id
oauth.kakao.client-secret=your-kakao-client-secret
oauth.google.client-id=your-google-client-id
oauth.google.client-secret=your-google-client-secret- 의존성 설치
./gradlew build- 애플리케이션 실행
./gradlew bootRuncurl -X POST http://localhost:8080/v1/auth/login \
-H "Content-Type: application/json" \
-d '{
"username": "testuser",
"password": "password123"
}'curl -X POST http://localhost:8080/v1/users \
-H "Content-Type: application/json" \
-d '{
"username": "newuser",
"password": "password123",
"email": "user@example.com",
"name": "홍길동",
"phone": "010-1234-5678",
"role": "USER"
}'curl -X POST http://localhost:8080/v1/auth/kakao \
-H "Content-Type: application/json" \
-d '{
"authorizationCode": "authorization_code_from_kakao",
"redirectUri": "your_redirect_uri"
}'curl -X POST http://localhost:8080/v1/auth/google \
-H "Content-Type: application/json" \
-d '{
"authorizationCode": "authorization_code_from_google",
"redirectUri": "your_redirect_uri"
}'curl -X GET http://localhost:8080/v1/users/me \
-H "Authorization: Bearer {accessToken}"curl -X PUT http://localhost:8080/v1/users/me/profile \
-H "Authorization: Bearer {accessToken}" \
-H "Content-Type: application/json" \
-d '{
"name": "새로운 이름",
"phone": "010-9876-5432",
"avatarUrl": "https://example.com/avatar.jpg",
"bio": "자기소개입니다."
}'curl -X GET "http://localhost:8080/v1/users/search?name=홍길동" \
-H "Authorization: Bearer {accessToken}"curl -X POST http://localhost:8080/v1/auth/refresh \
-H "Content-Type: application/json" \
-d '{
"refreshToken": "{refreshToken}"
}'{
"accessToken": "eyJhbGciOiJIUzI1NiJ9...",
"refreshToken": "eyJhbGciOiJIUzI1NiJ9...",
"tokenType": "Bearer",
"expiresIn": 1703123456789,
"userId": 1,
"username": "iu_8347",
"role": "USER"
}CustomException: 커스텀 비즈니스 예외IllegalArgumentException: 잘못된 인자 예외MethodArgumentNotValidException: 유효성 검증 실패 예외Exception: 기타 모든 예외
{
"code": "ERROR_CODE",
"message": "에러 메시지"
}application-dev.properties사용- 개발용 보안 설정 적용
- 디버그 로그 활성화
application-prod.properties사용- 프로덕션용 보안 설정 적용
- 로그 레벨 조정
- 중복 코드 제거 및 리팩토링
- 엔티티 관계 매핑 최적화
- 예외 처리 통합
- 타입 안전성 향상
- 코드 가독성 개선