9주차 미션 [카카]#21
Open
KateteDeveloper wants to merge 45 commits into
Open
Conversation
refactor: DTO 클래스를 record 타입으로 변환 및 Enum 상수 추가 - Home, Mission, Member, Review 도메인의 DTO 클래스(@Getter, @builder)를 Java record로 리팩토링 - DTO 내부 클래스의 불필요한 'Class' 접미사 제거 (예: MyDataReqClass -> MyDataReq) - Controller, Service, Converter 계층에 record 타입 변경 사항(생성자 및 접근자) 반영 - Gender, Term, SocialType Enum에 필요한 상수(MALE, FEMALE, REQUIRED, OPTIONAL 등) 추가 ```
```text
refactor: 리뷰 생성 API 수정 (marketId PathVariable 적용 및 ID 타입 Long 변경)
```
**Breakdown of the changes covered:**
* **Controller**: Updated the review creation endpoint to accept `marketId` as a `@PathVariable` (`/v1/create/{marketId}`).
* **DTO**: Removed `marketId` and `regionId` from `CreateReviewReq` since `marketId` is now handled via the URL path.
* **Entity**: Changed the data types of `marketId` and `regionId` in the `Review` entity from `Integer` to `Long`.
* **Service & Converter**: Updated methods to pass `marketId` from the controller down to the entity builder.
…based on your examples: ```text feat: update CreateReviewRes DTO and ReviewConverter, remove regionId from Review entity ``` **Here is a quick breakdown of the specific changes mapped in this commit:** * **`Review.java`**: Removed the `regionId` field and its corresponding column mapping. * **`ReviewResDTO.java`**: Populated the `CreateReviewRes` record with `reviewId`, `stars`, and `content` fields (previously an empty record). * **`ReviewConverter.java`**: Updated the `toCreateReview` method to properly map the `Review` entity data to the newly updated `CreateReviewRes` DTO instead of returning an empty object.
```text feat: enhance domain entities, introduce BaseEntity, and configure JPA mappings ``` **Breakdown of the specific changes covered in this commit:** * **Global**: * Introduced an abstract `BaseEntity` class with JPA auditing (`createdAt`, `updateAt`, `deleatedAt`) to unify and automate timestamp management across the application. * **Member Domain**: * Updated the `Member` entity to extend `BaseEntity` and added new fields for `detailAddress`, `socialUid`, and `socialType`. * Configured `Food` and `Term` entities, along with `MemberFood` and `MemberTerm` mapping entities to establish many-to-many relationships with the user. * Created the `FoodName` enum and updated the `Term` enum with new constants (AGE, SERVICE, PRIVACY, LOCATION, MARKETING). * **Review Domain**: * Created a new `Reply` entity (extending `BaseEntity`). * Updated the `Review` entity to include a `@OneToOne` relationship with `Reply` and changed its ID generation strategy to `IDENTITY`. * **Mission Domain**: * Refactored the `Mission` entity to extend `BaseEntity`, stripping out redundant explicitly defined timestamp and status fields. * Created the `MemberMission` mapping entity to manage the many-to-many relationship between users and missions, accompanied by a new `MissionStatus` enum (`IDLE`, `CHALLENGING`, `COMPLETE`).
- `Review.java`: 불필요한 `marketId` 필드를 삭제하고 `Store` 엔티티와의 `@ManyToOne` 연관관계 추가 - `StoreRepository.java`, `MemberMissionRepository.java`: 엔티티 조회를 위한 JpaRepository 인터페이스 신규 추가 - `ReviewService.java`, `ReviewConverter.java`: 리뷰 생성 시 전달받은 `storeId`로 `Store` 엔티티를 직접 조회하여 객체에 매핑하도록 로직 수정 - `MissionService.java`, `MissionConverter.java`: 사용자 미션 목록 조회 기준을 `Mission` 엔티티에서 `MemberMission` 매핑 엔티티로 변경 - `MissionResDTO.java`: `MissionList` DTO 내 `status` 필드 타입을 `String`에서 `MissionStatus` Enum 클래스로 변경 ```
- MemberController: 마이페이지 조회 API(`/v1/users/me`)의 HTTP 메서드를 POST에서 GET으로 변경하고, @RequestBody(DTO) 대신 @RequestParam으로 `id`를 받도록 수정 - MemberService: `getInfo` 메서드 파라미터를 `MemberReqDTO.GetInfo` 객체에서 `Long memberId`로 변경 - Member Entity: `socialType` 필드 타입을 String에서 `SocialType` Enum으로 변경 - Term Entity 및 Enum: 기존 `Term` Enum 클래스명을 `TermName`으로 변경하고 엔티티의 `name` 필드 타입에 반영 - MemberTerm, MemberFood Entity: 잘못 임포트된 Spring Data의 `@Id` 어노테이션을 JPA(`jakarta.persistence.Id`)로 수정 및 불필요한 import 제거 - MissionRepository: 사용하지 않는 `findByMemberId` 메서드 삭제 ```
- `MemberMissionRepository`에 `@Query`를 사용한 `findByMemberIdAndStatusIn` 커스텀 쿼리 메서드 추가 - N+1 문제를 방지하기 위해 `Mission`과 `Store` 엔티티를 `JOIN FETCH`로 함께 조회하도록 쿼리 작성 - `MissionService.getMissions()` 메서드에서 진행 중(`CHALLENGING`)이거나 완료(`COMPLETE`)된 미션만 조회하도록 상태 조건 필터링 추가 - `PageRequest` 객체를 사용해 데이터베이스 단에서 페이징 처리가 이루어지도록 로직을 개선하고, `hasNext` 판별 로직 수정 ```
…회 기능 추가 - HomeController: 미션 목록 조회 API(`/v1/missions`)에 특정 지역 필터링을 위한 `@RequestParam Long locationId` 파라미터 추가 - HomeService: 기존 전체 조회(findAll) 임시 로직을 제거하고, `Pageable`과 `locationId`를 활용해 해당 지역의 미션만 조회하도록 로직 변경 - HomeService: 다음 페이지 존재 여부(hasNext) 판단 기준을 `missions.size() == size`로 수정하여 페이지네이션 로직 개선 - MissionRepository: 스토어(store)와 위치(location) 정보를 페치 조인(JOIN FETCH)하여, 전달받은 `locationId`와 일치하는 미션 목록을 최신순(ORDER BY m.id DESC)으로 반환하는 `findByLocationId` 쿼리 메서드 추가 ```
- MissionRepository의 findByLocationId 메서드 반환 타입을 List에서 Slice로 변경 - HomeService의 getMissions 메서드에서 리스트 크기로 다음 페이지 존재 여부를 수동 계산하던 방식을 Slice의 hasNext() 메서드를 활용하도록 수정 ```
- HomeService의 getMyData 메서드 내 임시로 사용하던 RuntimeException("멤버 없음")을 커스텀 예외인 MemberException으로 교체
- 예외 발생 시 MemberErrorCode.MEMBER_NOT_FOUND 에러 코드를 사용하도록 수정
```
- SignUpReqDTO의 SignUpReqBody 레코드 내 필드에 @notblank, @Email, @pattern, @NotNull 등 유효성 검증 어노테이션 추가 - MemberController의 getSignUp 엔드포인트에서 요청 객체를 검증하도록 @Valid 어노테이션 적용 - MemberService에 있던 Member 엔티티 빌더 생성 로직을 MemberConverter.toMember()로 이동하여 계층 역할 분리 - MissionConverter.toCompleteMission() 응답 시 하드코딩된 완료 메시지를 Service 단에서 파라미터로 전달받도록 메서드 시그니처 수정 ```
- MemberMissionRepository: findByMemberIdAndStatusIn 메서드 반환 타입을 List에서 Slice로 변경 - MissionService: Slice 객체의 hasNext()를 활용하도록 페이징 처리 로직 수정 - MissionService: completeMission() 수행 시 완료 상태(COMPLETE)의 MemberMission을 DB에 저장하는 로직 추가 - MissionService: 하드코딩된 성공 응답 메시지를 MissionSuccessCode.OK 상수 값으로 대체 - MissionConverter: Mission 엔티티를 MemberMission으로 변환하는 toMemberMission() 메서드 추가 - Store: location 필드의 @manytoone 연관관계에 지연 로딩(FetchType.LAZY) 속성 적용 ```
- mission 패키지에 위치하던 Store 관련 클래스(Store, Location, StoreRepository)를 store 패키지로 이동 및 관련 import 구문 수정 - ReviewReqDTO.CreateReviewReq DTO에 커스텀 별점 검증(@ValidStars) 및 내용 글자 수 검증(@notblank, @SiZe) 어노테이션 추가 - 별점 입력을 0.5 단위, 0.5~5.0 범위로 검증하는 커스텀 어노테이션(@ValidStars) 및 검증 로직(ValidStarsValidator) 추가 - Review 엔티티에 Member 엔티티와의 @manytoone 연관관계(member_id) 매핑 추가 - Store 전용 커스텀 예외(StoreException) 및 에러 코드(StoreErrorCode)를 추가하고, ReviewService의 Store 조회 로직에 적용 ```
- `Address` Enum에 특별시/광역시 및 서울 주요 구 지역 상수 추가 - `SignUpReqDTO`의 `address` 필드 검증용 `@Pattern` 정규식에 추가된 `Address` 상수 목록 반영 - `Location` 엔티티의 식별자 컬럼명을 `location_id`로 명시하고, 주소 매핑 컬럼명을 `address`에서 `name`으로 변경 및 `nullable = false` 제약조건 추가 - `Store` 엔티티의 식별자 컬럼명을 `store_id`로 명시하고, `managerNumber` 및 `detailAddress` 필드 추가 - `Store` 엔티티의 `name`, `managerNumber`, `detailAddress`, `location_id`(연관관계) 컬럼에 `nullable = false` 제약조건 적용
- MissionController의 기본 URL을 `/api/v1`으로 변경하고, 가게 미션 생성(`POST /stores/{storeId}/missions`) 및 커서 기반 조회(`GET /stores/{storeId}/missions`) API 추가
- MissionService에 `StoreRepository`를 연동하여 새로운 미션을 생성하는 로직과 커서(Cursor) 기반 페이지네이션을 적용한 미션 조회 로직 구현
- MissionRepository에 가게 ID와 커서(ID 내림차순)를 조건으로 미션을 조회하는 메서드(`findMissionsByStore_IdAndIdLessThanOrderByIdDesc` 등) 추가
- MissionReqDTO에 미션 생성 요청용 `CreateMission` record를 추가하고 데이터 유효성 검증(Validation) 어노테이션 적용
- MissionResDTO에 응답용 `GetMissionRes`와 커서 페이징 데이터 처리를 위한 공통 포맷인 `Pagination` record 추가
- MissionConverter에 신규 DTO와 Entity 간의 데이터 변환을 처리하는 매핑 메서드(`toMission`, `toGetMission`, `toPagination` 등) 추가
- MissionErrorCode에 잘못된 쿼리 요청을 처리하는 `QUERY_NOT_VALID` 예외 코드를 추가하고, MissionSuccessCode에 `CREATED` 성공 코드 추가
- `GeneralExceptionAdvice`에 `MethodArgumentNotValidException` 핸들러를 추가하여 필드별 유효성 검증 에러 메시지 반환 로직 구현 - `SignUpReqDTO`, `MissionReqDTO`, `ReviewReqDTO`의 검증 어노테이션(@notblank, @pattern, @SiZe, @NotNull 등)에 구체적인 `message` 속성 추가 - `MissionController`의 가게 미션 조회 API(`getMissions`) 반환 타입을 `List`에서 `Pagination` 구조로 변경 - 프로젝트 전반에 걸쳐 record 기반 DTO 클래스의 빈 중괄호 포맷팅 수정 - 다수의 Controller, Service, Repository, Entity 계층에서 사용하지 않는 불필요한 import 문 제거 및 와일드카드 import(`lombok.*`)를 명시적 선언으로 변경
- `MissionController`에 내가 진행중인 미션 조회 엔드포인트(`/missions/my`) 추가 - `MissionReqDTO`에 회원 ID 및 페이지네이션 정보를 받는 `GetMyMissionsReq` DTO 추가 - `MissionResDTO`에 미션 목록 응답을 처리하는 `MyMissionList`, `MyMissionPage` DTO 추가 - `MissionService`에 `CHALLENGING`, `COMPLETE` 상태의 미션을 페이징하여 반환하는 `getMyMissions` 비즈니스 로직 구현 ``` --- ```text ♻️ refactor(converter): 미션 응답 Converter 파라미터 및 메서드명 수정 - `MissionConverter`의 변환 메서드명을 `toMissionList` -> `toMyMissionList`, `toMissionPage` -> `toMyMissionPage`로 각각 변경 - 응답 변환 로직에서 `List<MemberMission>` 대신 `Slice<MemberMission>`을 직접 파라미터로 받도록 개선하여 불필요한 `hasNext` 인자 제거 - 데이터 리스트 변환 시 `Collectors.toList()` 호출을 `toList()`로 간소화 ``` --- ```text 🗄️ db(entity): Store 엔티티 식별자 매핑 컬럼명 변경 - `Store` 엔티티의 기본키 컬럼 매핑을 `@Column(name = "store_id")`에서 `@Column(name = "id")`로 변경 ```
- page 파라미터에 `@Min(value = 0)` 어노테이션을 추가하여 0 이상 값만 허용하도록 설정 - size 파라미터에 `@Min(value = 1)` 어노테이션을 추가하여 1 이상 값만 허용하도록 설정
- `nextCursor` 변수의 초기값을 "-1"로 할당 - `missionList`의 결과가 비어있지 않은 경우에만 `getLast()`를 호출하여 `nextCursor`를 업데이트하도록 조건문 추가 (빈 리스트 접근으로 인한 예외 방지) - `query` 파라미터 검증 로직의 불필요한 `switch` 문을 `equalsIgnoreCase`를 활용한 `if` 문으로 단순화하여 가독성 개선
- ReviewService의 별점 순 정렬 시 커서를 `stars:id` 형태로 파싱하여 동일 별점 데이터도 정상적으로 페이징되도록 로직 수정 - ReviewRepository에 별점 및 ID 복합 조건을 처리하는 `findByMemberIdAndStarsLessThanOrStarsAndIdLessThan` 커스텀 쿼리 메서드 추가 - 유효하지 않은 정렬 기준 요청 시 사용할 `QUERY_NOT_VALID` 에러 코드를 ReviewErrorCode에 추가 - ReviewService에서 잘못된 정렬 기준 처리 시 기존 RuntimeException 대신 추가된 커스텀 예외(ReviewException)를 던지도록 변경
✨ feat(config): Spring Security 설정 및 의존성 추가 - build.gradle에 spring-boot-starter-security 및 spring-security-test 의존성 추가 - SecurityConfig 클래스를 생성하여 SecurityFilterChain 및 PasswordEncoder(BCryptPasswordEncoder) 빈 등록 - Swagger 관련 URI(/swagger-ui/**, /v3/api-docs/** 등) 및 /auth/** 경로에 대한 접근을 허용(permitAll)하도록 설정 - 기본 폼 로그인 및 로그아웃(URL 매핑 및 성공 후 리다이렉트 URL) 설정 적용 - global/config 패키지 내부에 빈 내용의 SwaggerConfig 클래스 파일 생성 ```
- SignUpReqDTO에 약관 동의 정보(AgreeReq), 선호 음식 리스트(foodList), 상세 주소(detailAddress) 필드 추가 및 불필요한 필드(phoneNumber, agreedId) 제거 - TermRepository, FoodRepository, MemberTermRepository, MemberFoodRepository JpaRepository 인터페이스 4종 신규 생성 - MemberErrorCode에 약관(TERM_NOT_FOUND) 및 음식(FOOD_NOT_FOUND) 조회를 위한 예외 코드 추가 - MemberConverter에 회원과 약관, 회원과 음식을 연결하는 매핑 엔티티(MemberTerm, MemberFood) 변환 메서드 추가 - MemberService의 signUp() 메서드에서 회원가입 요청 시 전달받은 약관 동의 내역과 선호 음식을 검증하고 연관관계 엔티티로 저장하도록 수정
✨ feat(security): Spring Security 인증 및 예외 처리 클래스 추가 - UserDetails 인터페이스를 구현하여 Member 엔티티 정보를 담는 AuthMember 클래스 추가 - MemberRepository를 통해 이메일 기반으로 사용자를 조회하는 CustomUserDetailsService 추가 - 인증 예외 발생 시 UNAUTHORIZED 커스텀 JSON 응답을 반환하는 CustomEntryPoint 추가 - 인가 예외 발생 시 UNAUTHORIZED 커스텀 JSON 응답을 반환하는 CustomAccessDenied 추가 ```
… 컬럼명 수정 - FoodName.java: 'Italian' 상수를 대문자 'ITALIAN'으로 변경 - FoodRepository.java: findByName() 메서드의 파라미터 타입을 String에서 FoodName Enum 타입으로 변경 - Location.java: ID 컬럼 매핑 이름을 'location_id'에서 'id'로 변경
- Umc10thApplication 메인 클래스에 @EnableJpaAuditing 어노테이션 추가
- HttpSecurity 설정에 `exceptionHandling()`을 추가하여 커스텀 예외 처리기 등록 - 접근 권한 거부 처리를 위한 `customAccessDenied()` 메서드 및 Bean 추가 - 인증 실패 처리를 위한 `customEntryPoint()` 메서드 및 Bean 추가
- SignUpReq 레코드의 `birth`, `foodList` 필드에 API 문서화를 위한 `@Schema` 어노테이션(description, example) 추가 - AgreeReq 레코드의 모든 boolean 필드(`age`, `service`, `privacy`, `location`, `marketing`)에 `@Schema(example = "true")` 속성 명시
✨ feat(service): 회원가입 비밀번호 암호화 로직 추가 및 음식 카테고리 Enum 매핑 수정 - `MemberService`의 회원가입(`getSignUp`) 로직에 `PasswordEncoder`를 활용한 비밀번호 암호화 처리 추가 - `MemberConverter`의 `toMember` 메서드가 암호화된 비밀번호(`encodedPassword`)를 주입받아 엔티티를 생성하도록 매개변수 수정 - `MemberService` 내 선호 음식 리스트 조회 시, 문자열을 대문자로 변환(`toUpperCase()`) 후 `FoodName` Enum 상수와 매핑되도록 로직 수정 --- ♻️ refactor(controller): 마이페이지 조회 API 컨트롤러 분리 및 미사용 API 주석 처리 - 기존 `MemberController`에 위치하던 마이페이지 조회 API(`/v1/users/me`)를 신규 생성한 `MemberMyPageController`로 이동하여 분리 - `MemberController` 내 불필요한 테스트용 API(`/test`, `/singleParameter`)를 블록 주석 처리하여 비활성화 --- 🔧 chore(config): API 경로 보안 인증 규칙 추가 - `SecurityConfig` 파일에서 `/api/**` 하위 모든 요청에 대해 인증(`authenticated()`)을 요구하도록 보안 설정 추가 --- 🗄️ db(repository): 이메일 기반 회원 조회 메서드 추가 - `MemberRepository`에 이메일을 조건으로 회원을 조회하는 `findByEmail` 쿼리 메서드 추가
- `MemberService`의 회원가입(getSignUp) 로직에 이메일 중복 시 예외(`DUPLICATE_EMAIL`)를 발생시키는 검증 단계 추가 - `MemberErrorCode`에 이메일 중복 에러 처리용 상수(`DUPLICATE_EMAIL`, 409 CONFLICT) 추가 - `MemberRepository`에 이메일 존재 여부를 확인하는 `existsByEmail()` 메서드 추가 - `MemberService` 및 `MemberErrorCode` 내부의 불필요한 주석 제거
- MemberService에 필수 약관(AGE, SERVICE, PRIVACY) 동의 여부를 확인하는 검증 로직 추가 - 필수 약관 중 하나라도 동의하지 않았을 경우 예외를 발생시키도록 처리 - MemberErrorCode에 REQUIRED_TERM_NOT_AGREED(MEMBER400_1) 에러 코드 추가
- MemberService에서 잘못된 음식 이름(foodStr) 입력 시 발생하는 IllegalArgumentException 예외 처리 로직 추가 - MemberErrorCode에 유효하지 않은 음식 값에 대한 에러 코드(INVALID_FOOD_NAME, MEMBER400_2) 추가
- JWT AccessToken 생성, 유효성 검증, Payload(이메일) 추출 기능을 담당하는 `JwtUtil` 클래스 추가 - HTTP 요청 헤더에서 토큰을 추출하여 검증한 후, 유효한 경우 `SecurityContextHolder`에 인증 객체를 저장하는 `JwtAuthFilter` 구현 - 필터 내 인증 과정에서 발생하는 예외를 `ApiResponse` 형식을 활용하여 `UNAUTHORIZED` 에러로 반환하도록 예외 처리 구현
- `build.gradle`에 JWT 구현을 위한 `jjwt` 관련 라이브러리(api, impl, jackson)와 `spring-boot-configuration-processor` 의존성 추가 - `application.yml`에 JWT 시크릿 키(`secretKey`) 및 액세스 토큰 만료 시간(`expiration.access`) 설정 추가
- email, password 필드를 포함하는 LoginReqDTO 내부 레코드(LoginReqBody) 추가 - accessToken 필드를 포함하는 LoginResDTO 내부 레코드(LoginResBody) 추가
- SecurityConfig 내에 JwtAuthFilter를 빈으로 생성하고, UsernamePasswordAuthenticationFilter 이전에 수행되도록 필터 체인에 추가 - 기존 폼 로그인(formLogin) 방식과 세션 관리(sessionManagement) 기능 비활성화 - JWT 검증에 필요한 JwtUtil 및 CustomUserDetailsService 의존성 주입을 위해 클래스에 @requiredargsconstructor 추가 ```
- MemberController에 `/login` POST 엔드포인트 추가 - MemberService에 로그인 처리 로직(이메일 기반 회원 조회, 비밀번호 검증, JWT Access Token 발급) 추가 - Member 엔티티의 email 컬럼에 `unique = true` 제약조건 추가 - MemberErrorCode에 비밀번호 불일치 예외를 처리하는 `INVALID_PASSWORD` 에러 코드 추가 - MemberController와 MemberService의 DTO import 문을 와일드카드(*)로 변경
- MemberMyPageController의 내 정보 조회 API 경로를 `/v1/users/me`에서 `/v2/users/me`로 변경 - API 파라미터를 `@RequestParam Long id`에서 `@AuthenticationPrincipal AuthMember member`로 수정하여 Spring Security 인증 객체 적용 - MemberService의 `getInfo` 메서드가 `AuthMember`를 파라미터로 받도록 수정하고, 불필요한 MemberRepository 조회 로직 제거 - AuthMember(UserDetails 구현체)의 `getUsername()` 반환값을 회원의 이름(name)에서 이메일(email)로 변경
- SecurityConfig에 OAuth2 로그인(엔드포인트, 콜백, 유저 서비스, 성공 핸들러) 관련 설정 추가 - SecurityConfig에 OAuthSuccessHandler 빈 생성 및 등록 메서드 추가 - JwtUtil에 JWT 토큰 클레임에서 SocialType을 추출해 반환하는 getSocialType 메서드 추가
…ository 기능 추가 - `MemberResDTO`에 accessToken을 반환하는 `Login` record 추가 - `MemberConverter`에 `OAuthDTO`를 `Member` 엔티티로 변환하는 `toMember`와 로그인 응답용 `toLogin` 메서드 추가 - `MemberErrorCode`에 지원하지 않는 소셜 로그인 에러 코드(`NOT_SUPPORT_SOCIAL_PROVIDER`) 추가 - `MemberRepository`에 `SocialType`과 `socialUid`로 회원을 조회하는 `findBySocialTypeAndSocialUid` 메서드 추가 ```
- 소셜 로그인 데이터 규격을 정의하는 OAuthDTO 인터페이스와 카카오 로그인용 KakaoDTO 추가 - Spring Security의 OAuth2User를 구현하여 Member 엔티티와 인증 속성(attributes)을 관리하는 OAuthMember 추가 - OAuth 인증 성공 시 JWT(AccessToken)를 발급하고 ApiResponse 통일 규격으로 JSON 응답을 반환하는 OAuthSuccessHandler 추가 ```
- `CustomOAuthService` 클래스를 신규 추가하여 카카오(Kakao) 소셜 로그인 시 사용자 정보를 추출하고, 기존 회원이 아니면 DB에 새로 저장하는 OAuth2 인증 로직 구현 - `CustomUserDetailsService` 클래스에 소셜 타입(`SocialType`)과 식별자(`socialUid`)를 기반으로 DB에서 사용자를 조회하는 `loadUserByUidAndSocialType` 메서드 추가 - 기존 `loadUserByUsername` 메서드의 반환부와 예외 처리(UsernameNotFoundException) 구문 구조 정리
- `AuthMember` 클래스의 `getUsername()` 메서드 내부에 `return member.getSocialUid();` 구문을 주석 처리하여 추가
yangjiae12
reviewed
May 31, 2026
Comment on lines
+87
to
+90
| .subject(member.getUsername()) // User 이메일을 Subject로 | ||
| .claim("role", authorities) | ||
| .claim("email", member.getUsername()) | ||
| .issuedAt(Date.from(now)) // 언제 발급한지 |
Member
There was a problem hiding this comment.
sub Claim에 이미 이메일을 저장하고 있는데 email Claim에도 동일한 값을 저장하고 있는 것 같습니다. 별도 활용 계획이 없다면 중복 데이터를 제거해도 될 것 같습니다!
Comment on lines
+49
to
+51
| String email = jwtUtil.getEmail(token); | ||
| // 인증 객체 생성: 이메일로 찾아온 뒤, 인증 객체 생성 | ||
| UserDetails user = customUserDetailsService.loadUserByUsername(email); |
Member
There was a problem hiding this comment.
JWT에 email, role 정보가 포함되어 있는데 인증 시 다시 DB 조회를 수행하고 있네요~ 만약 사용자 상태를 실시간으로 반영할 필요가 없다면 Claim 정보만으로 Authentication을 구성하는 방식도 고려해볼 수 있을 것 같습니다.
| response.setStatus(code.getStatus().value()); | ||
|
|
||
| // 인증 객체 컨테이너에서 OAuth 인증 객체 가져오기 | ||
| OAuthMember member = (OAuthMember) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); |
Member
There was a problem hiding this comment.
onAuthenticationSuccess()의 Authentication 파라미터를 직접 활용해도 될 것 같습니다!
yangjiae12
approved these changes
May 31, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
📌 구현 결과
회원가입 (
POST /auth/v1/signup)로그인 (
POST /auth/login)-
JWT 인증 필터
JwtAuthFilter- Bearer 토큰 검증 및 SecurityContext 등록마이페이지 (
GET /api/v2/users/me)@AuthenticationPrincipal로 인증된 유저 정보 조회카카오 소셜 로그인 (구조 구현)
CustomOAuthService- 카카오 유저 정보 파싱OAuthSuccessHandler- 로그인 성공 시 JWT 발급예외 코드 추가
DUPLICATE_EMAIL409REQUIRED_TERM_NOT_AGREED400INVALID_FOOD_NAME400INVALID_PASSWORD401NOT_SUPPORT_SOCIAL_PROVIDER400❓ 리뷰 요청
🤔 질문
💬 기타 공유 사항