From 39574544b50eb084a30b4259f4828e6413cd5332 Mon Sep 17 00:00:00 2001 From: 2u6in Date: Thu, 28 May 2026 15:05:27 +0900 Subject: [PATCH 1/8] =?UTF-8?q?chore:=20jwt=20=EC=9D=98=EC=A1=B4=EC=84=B1?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/build.gradle b/build.gradle index a1dc7ce..26a8178 100644 --- a/build.gradle +++ b/build.gradle @@ -36,6 +36,12 @@ dependencies { // Security implementation 'org.springframework.boot:spring-boot-starter-security' testImplementation 'org.springframework.security:spring-security-test' + + // Jwt + implementation 'io.jsonwebtoken:jjwt-api:0.12.3' + implementation 'io.jsonwebtoken:jjwt-impl:0.12.3' + implementation 'io.jsonwebtoken:jjwt-jackson:0.12.3' + implementation 'org.springframework.boot:spring-boot-configuration-processor' } tasks.named('test') { From df3ebce8f2af4305ccc53cc860723a48b5eca9d2 Mon Sep 17 00:00:00 2001 From: 2u6in Date: Sat, 30 May 2026 14:32:34 +0900 Subject: [PATCH 2/8] =?UTF-8?q?feat:=20JWT=20=EC=9D=B8=EC=A6=9D=20?= =?UTF-8?q?=ED=95=84=ED=84=B0=20=EC=B6=94=EA=B0=80=20=EB=B0=8F=20Security?= =?UTF-8?q?=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../member/repository/TermRepository.java | 2 +- .../domain/member/service/MemberService.java | 2 +- .../umc/global/config/SecurityConfig.java | 21 ++++- .../global/security/filter/JwtAuthFilter.java | 66 ++++++++++++++++ .../umc/global/security/util/JwtUtil.java | 76 +++++++++++++++++++ src/main/resources/application.yml | 26 ++++--- 6 files changed, 177 insertions(+), 16 deletions(-) create mode 100644 src/main/java/umc/global/security/filter/JwtAuthFilter.java create mode 100644 src/main/java/umc/global/security/util/JwtUtil.java diff --git a/src/main/java/umc/domain/member/repository/TermRepository.java b/src/main/java/umc/domain/member/repository/TermRepository.java index 11a2932..19c1803 100644 --- a/src/main/java/umc/domain/member/repository/TermRepository.java +++ b/src/main/java/umc/domain/member/repository/TermRepository.java @@ -7,7 +7,7 @@ import java.util.List; public interface TermRepository extends JpaRepository { - List findAllByRequired(boolean isRequired); + List findAllByIsRequired(boolean isRequired); @Query(""" select t.id diff --git a/src/main/java/umc/domain/member/service/MemberService.java b/src/main/java/umc/domain/member/service/MemberService.java index 0940c7b..483c8ec 100644 --- a/src/main/java/umc/domain/member/service/MemberService.java +++ b/src/main/java/umc/domain/member/service/MemberService.java @@ -73,7 +73,7 @@ public MemberResDTO.SignUpRes signUp(MemberReqDTO.@Valid SignUpReq dto) { } //필수 정책 id 목록 - List requiredTermId = termRepository.findAllByRequired(true) + List requiredTermId = termRepository.findAllByIsRequired(true) .stream() .map(Term::getId) .toList(); diff --git a/src/main/java/umc/global/config/SecurityConfig.java b/src/main/java/umc/global/config/SecurityConfig.java index b2d0699..48aa9a0 100644 --- a/src/main/java/umc/global/config/SecurityConfig.java +++ b/src/main/java/umc/global/config/SecurityConfig.java @@ -1,5 +1,6 @@ package umc.global.config; +import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; @@ -7,13 +8,21 @@ import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import umc.global.security.exception.CustomAccessDenied; import umc.global.security.exception.CustomEntryPoint; +import umc.global.security.filter.JwtAuthFilter; +import umc.global.security.service.CustomUserDetailsService; +import umc.global.security.util.JwtUtil; @EnableWebSecurity @Configuration +@RequiredArgsConstructor public class SecurityConfig { + private final JwtUtil jwtUtil; + private final CustomUserDetailsService customUserDetailsService; + private final String[] allowUris = { // Swagger 허용 "/swagger-ui/**", @@ -30,10 +39,9 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti .requestMatchers(allowUris).permitAll() .anyRequest().authenticated() ) - .formLogin(form -> form - .defaultSuccessUrl("/swagger-ui/index.html", true) - .permitAll() - ) + .formLogin(AbstractHttpConfigurer::disable) + .sessionManagement(AbstractHttpConfigurer::disable) + .addFilterBefore(jwtAuthFilter(), UsernamePasswordAuthenticationFilter.class) .logout(logout -> logout .logoutUrl("/logout") .logoutSuccessUrl("/login?logout") @@ -60,4 +68,9 @@ public CustomAccessDenied customAccessDenied(){ public CustomEntryPoint customEntryPoint(){ return new CustomEntryPoint(); } + + @Bean + public JwtAuthFilter jwtAuthFilter(){ + return new JwtAuthFilter(jwtUtil, customUserDetailsService); + } } diff --git a/src/main/java/umc/global/security/filter/JwtAuthFilter.java b/src/main/java/umc/global/security/filter/JwtAuthFilter.java new file mode 100644 index 0000000..70268fc --- /dev/null +++ b/src/main/java/umc/global/security/filter/JwtAuthFilter.java @@ -0,0 +1,66 @@ +package umc.global.security.filter; + +import com.fasterxml.jackson.databind.ObjectMapper; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import lombok.NonNull; +import lombok.RequiredArgsConstructor; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.web.filter.OncePerRequestFilter; +import umc.global.apiPayload.ApiResponse; +import umc.global.apiPayload.code.BaseErrorCode; +import umc.global.apiPayload.code.GeneralErrorCode; +import umc.global.security.service.CustomUserDetailsService; +import umc.global.security.util.JwtUtil; + +import java.io.IOException; + +@RequiredArgsConstructor +public class JwtAuthFilter extends OncePerRequestFilter { + + private final JwtUtil jwtUtil; + private final CustomUserDetailsService customUserDetailsService; + + @Override + protected void doFilterInternal( + @NonNull HttpServletRequest request, + @NonNull HttpServletResponse response, + @NonNull FilterChain filterChain + ) throws ServletException, IOException { + + try { + String token = request.getHeader("Authorization"); + if (token == null || !token.startsWith("Bearer ")) { + filterChain.doFilter(request, response); + return; + } + token = token.replace("Bearer ", ""); + if (jwtUtil.isValid(token)) { + String email = jwtUtil.getEmail(token); + UserDetails user = customUserDetailsService.loadUserByUsername(email); + Authentication auth = new UsernamePasswordAuthenticationToken( + user, + null, + user.getAuthorities() + ); + SecurityContextHolder.getContext().setAuthentication(auth); + } + filterChain.doFilter(request, response); + } catch (Exception e) { + ObjectMapper mapper = new ObjectMapper(); + BaseErrorCode code = GeneralErrorCode.UNAUTHORIZED; + + response.setContentType("application/json;charset=UTF-8"); + response.setStatus(code.getStatus().value()); + + ApiResponse errorResponse = ApiResponse.onFailure(code,null); + + mapper.writeValue(response.getOutputStream(), errorResponse); + } + } +} diff --git a/src/main/java/umc/global/security/util/JwtUtil.java b/src/main/java/umc/global/security/util/JwtUtil.java new file mode 100644 index 0000000..694770c --- /dev/null +++ b/src/main/java/umc/global/security/util/JwtUtil.java @@ -0,0 +1,76 @@ +package umc.global.security.util; + +import io.jsonwebtoken.*; +import io.jsonwebtoken.security.Keys; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.stereotype.Component; +import umc.global.security.entity.AuthMember; + +import javax.crypto.SecretKey; +import java.nio.charset.StandardCharsets; +import java.time.Duration; +import java.time.Instant; +import java.util.Date; +import java.util.stream.Collectors; + +@Component +public class JwtUtil { + + private final SecretKey secretKey; + private final Duration accessExpiration; + + public JwtUtil( + @Value("${jwt.token.secretKey}") String secret, + @Value("${jwt.token.expiration.access}") Long accessExpiration + ) { + this.secretKey = Keys.hmacShaKeyFor(secret.getBytes(StandardCharsets.UTF_8)); + this.accessExpiration = Duration.ofMillis(accessExpiration); + } + + public String createAccessToken(AuthMember member){ + return createToken(member, accessExpiration); + } + + private String createToken(AuthMember member, Duration accessExpiration) { + Instant now = Instant.now(); + + String authorities = member.getAuthorities().stream() + .map(GrantedAuthority::getAuthority) + .collect(Collectors.joining(",")); + + return Jwts.builder() + .subject(member.getUsername()) + .claim("role", authorities) + .claim("email", member.getUsername()) + .issuedAt(Date.from(now)) + .expiration(Date.from(now.plus(accessExpiration))) + .signWith(secretKey) + .compact(); + } + + public String getEmail (String token){ + try{ + return getClaims(token).getPayload().getSubject(); + } catch (JwtException e){ + return null; + } + } + + private Jws getClaims(String token) throws JwtException { + return Jwts.parser() + .verifyWith(secretKey) // 서명 검증 키 설정 + .clockSkewSeconds(60) // 최대 60초 시계 오차 허용 + .build() + .parseSignedClaims(token); // 파싱 + 검증 실행 + } + + public boolean isValid(String token){ + try{ + getClaims(token); + return true; + } catch (JwtException e){ + return false; + } + } +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index e70ca3b..967a4aa 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,19 +1,25 @@ spring: application: - name: "umc" # "umc10th" + name: "umc" datasource: - driver-class-name: com.mysql.cj.jdbc.Driver # MySQL JDBC ???? ??? ?? - url: ${DB_URL} # jdbc:mysql://localhost:3306/{???????} - username: ${DB_USER} # MySQL ?? ?? - password: ${DB_PW} # MySQL ???? + driver-class-name: com.mysql.cj.jdbc.Driver + url: ${DB_URL} + username: ${DB_USER} + password: ${DB_PW} jpa: - database: mysql # ??? ?????? ?? ?? (MySQL) - database-platform: org.hibernate.dialect.MySQLDialect # Hibernate?? ??? MySQL ??(dialect) ?? - show-sql: true # ??? SQL ??? ??? ???? ?? ?? + database: mysql + database-platform: org.hibernate.dialect.MySQLDialect + show-sql: true hibernate: - ddl-auto: update # ?????? ?? ? ?????? ???? ??? ?? + ddl-auto: update properties: hibernate: - format_sql: true # ???? SQL ??? ?? ?? ??? \ No newline at end of file + format_sql: true + +jwt: + token: + secretKey: ${JWT_SECRET_KEY} + expiration: + access: 1800000 # 30분 \ No newline at end of file From dbf1bc6675e0b3846551842e8c84c85681abd119 Mon Sep 17 00:00:00 2001 From: 2u6in Date: Sun, 31 May 2026 00:26:52 +0900 Subject: [PATCH 3/8] =?UTF-8?q?feat:=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../member/controller/MemberController.java | 8 +++++ .../umc/domain/member/dto/MemberReqDTO.java | 20 ++++++++---- .../umc/domain/member/dto/MemberResDTO.java | 6 ++++ .../domain/member/service/MemberService.java | 32 +++++++++++++++++++ .../umc/global/config/SecurityConfig.java | 9 ++++++ 5 files changed, 69 insertions(+), 6 deletions(-) diff --git a/src/main/java/umc/domain/member/controller/MemberController.java b/src/main/java/umc/domain/member/controller/MemberController.java index 8ee8287..e7aa93f 100644 --- a/src/main/java/umc/domain/member/controller/MemberController.java +++ b/src/main/java/umc/domain/member/controller/MemberController.java @@ -41,4 +41,12 @@ public ApiResponse signup( ){ return ApiResponse.onSuccess(MemberSuccessCode.CREATED, memberService.signUp(dto)); } + + //로그인 + @PostMapping("v1/auth/members/login") + public ApiResponse login( + @RequestBody @Valid MemberReqDTO.LoginReq dto + ){ + return ApiResponse.onSuccess(MemberSuccessCode.MEMBER_SUCCESS, memberService.login(dto)); + } } diff --git a/src/main/java/umc/domain/member/dto/MemberReqDTO.java b/src/main/java/umc/domain/member/dto/MemberReqDTO.java index 0b2cc94..5b828eb 100644 --- a/src/main/java/umc/domain/member/dto/MemberReqDTO.java +++ b/src/main/java/umc/domain/member/dto/MemberReqDTO.java @@ -1,8 +1,6 @@ package umc.domain.member.dto; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Past; +import jakarta.validation.constraints.*; import umc.domain.member.enums.Gender; import java.time.LocalDate; @@ -16,7 +14,11 @@ public record MyPageReqDTO( ){} public record SignUpReq( - List agreedTermsIds, + @NotBlank + @Email + String email, + @NotBlank + String password, @NotBlank String name, @NotNull @@ -26,11 +28,17 @@ public record SignUpReq( LocalDate birth, @NotBlank String address, + @NotEmpty + List agreedTermsIds, List userFood, + String phoneNumber + ){} + + public record LoginReq( @NotBlank + @Email String email, @NotBlank - String password, - String phoneNumber + String password ){} } diff --git a/src/main/java/umc/domain/member/dto/MemberResDTO.java b/src/main/java/umc/domain/member/dto/MemberResDTO.java index 99a6bcf..0ddccf8 100644 --- a/src/main/java/umc/domain/member/dto/MemberResDTO.java +++ b/src/main/java/umc/domain/member/dto/MemberResDTO.java @@ -28,4 +28,10 @@ public record SignUpRes( Long memberId, LocalDateTime createdAt ){} + + //로그인 + @Builder + public record LoginRes( + String accessToken + ){} } diff --git a/src/main/java/umc/domain/member/service/MemberService.java b/src/main/java/umc/domain/member/service/MemberService.java index 483c8ec..119d70d 100644 --- a/src/main/java/umc/domain/member/service/MemberService.java +++ b/src/main/java/umc/domain/member/service/MemberService.java @@ -2,6 +2,10 @@ import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -20,6 +24,8 @@ import umc.domain.member.exception.code.MemberErrorCode; import umc.domain.member.exception.code.TermErrorCode; import umc.domain.member.repository.*; +import umc.global.security.entity.AuthMember; +import umc.global.security.util.JwtUtil; import java.util.List; @@ -33,6 +39,8 @@ public class MemberService { private final MemberTermRepository memberTermRepository; private final FoodRepository foodRepository; private final MemberFoodRepository memberFoodRepository; + private final AuthenticationManager authenticationManager; + private final JwtUtil jwtUtil; @Transactional(readOnly = true) public MemberResDTO.MyPageResDTO getInfo(MemberReqDTO.MyPageReqDTO dto) { @@ -128,4 +136,28 @@ public MemberResDTO.SignUpRes signUp(MemberReqDTO.@Valid SignUpReq dto) { return MemberConverter.toSignUpRes(savedMember); } + + public MemberResDTO.LoginRes login(MemberReqDTO.@Valid LoginReq dto) { + try{ + + //인증 과정을 authenticationManager에게 넘김 + Authentication authentication = authenticationManager.authenticate( + new UsernamePasswordAuthenticationToken( + dto.email(), + dto.password() + ) + ); + + AuthMember authMember = (AuthMember) authentication.getPrincipal(); + + String token = jwtUtil.createAccessToken(authMember); + + return MemberResDTO.LoginRes.builder() + .accessToken(token) + .build(); + + } catch (AuthenticationException e){ + throw new MemberException(MemberErrorCode.MEMBER_NOT_FOUND); + } + } } diff --git a/src/main/java/umc/global/config/SecurityConfig.java b/src/main/java/umc/global/config/SecurityConfig.java index 48aa9a0..0b84bf7 100644 --- a/src/main/java/umc/global/config/SecurityConfig.java +++ b/src/main/java/umc/global/config/SecurityConfig.java @@ -3,6 +3,8 @@ import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; @@ -73,4 +75,11 @@ public CustomEntryPoint customEntryPoint(){ public JwtAuthFilter jwtAuthFilter(){ return new JwtAuthFilter(jwtUtil, customUserDetailsService); } + + @Bean + public AuthenticationManager authenticationManager( + AuthenticationConfiguration configuration + )throws Exception{ + return configuration.getAuthenticationManager(); + } } From 19a2cc4426a2f313fbfc482a31b67e7549962d7a Mon Sep 17 00:00:00 2001 From: 2u6in Date: Sun, 31 May 2026 00:40:23 +0900 Subject: [PATCH 4/8] =?UTF-8?q?refactor:=20=ED=86=A0=ED=81=B0=20=EC=A0=95?= =?UTF-8?q?=EB=B3=B4=EB=A5=BC=20=EC=9D=B4=EC=9A=A9=ED=95=B4=EC=84=9C=20?= =?UTF-8?q?=EB=A7=88=EC=9D=B4=20=ED=8E=98=EC=9D=B4=EC=A7=80=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=ED=95=98=EA=B2=8C=20=EB=A6=AC=ED=8C=A9=ED=86=A0?= =?UTF-8?q?=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../umc/domain/member/controller/MemberController.java | 8 +++++--- .../java/umc/domain/member/service/MemberService.java | 9 ++------- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/main/java/umc/domain/member/controller/MemberController.java b/src/main/java/umc/domain/member/controller/MemberController.java index e7aa93f..29dcc6f 100644 --- a/src/main/java/umc/domain/member/controller/MemberController.java +++ b/src/main/java/umc/domain/member/controller/MemberController.java @@ -2,6 +2,7 @@ import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; +import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.*; import umc.domain.member.dto.MemberReqDTO; import umc.domain.member.dto.MemberResDTO; @@ -10,6 +11,7 @@ import umc.global.apiPayload.ApiResponse; import umc.global.apiPayload.code.BaseSuccessCode; import umc.global.apiPayload.code.GeneralSuccessCode; +import umc.global.security.entity.AuthMember; @RestController @RequiredArgsConstructor @@ -20,10 +22,10 @@ public class MemberController { //마이 페이지 @PostMapping("/v1/members/me") public ApiResponse getInfo( - @RequestBody @Valid MemberReqDTO.MyPageReqDTO dto - ){ + @AuthenticationPrincipal AuthMember member + ){ BaseSuccessCode code = MemberSuccessCode.MEMBER_SUCCESS; - return ApiResponse.onSuccess(code, memberService.getInfo(dto)); + return ApiResponse.onSuccess(code, memberService.getInfo(member)); } //보유 포인트 조회 diff --git a/src/main/java/umc/domain/member/service/MemberService.java b/src/main/java/umc/domain/member/service/MemberService.java index 119d70d..d94db5c 100644 --- a/src/main/java/umc/domain/member/service/MemberService.java +++ b/src/main/java/umc/domain/member/service/MemberService.java @@ -43,13 +43,8 @@ public class MemberService { private final JwtUtil jwtUtil; @Transactional(readOnly = true) - public MemberResDTO.MyPageResDTO getInfo(MemberReqDTO.MyPageReqDTO dto) { - Long memberId = dto.id(); - Member member = memberRepository.findById(memberId).orElseThrow( - ()->new MemberException(MemberErrorCode.MEMBER_NOT_FOUND) - ); - - return MemberConverter.toGetInfo(member); + public MemberResDTO.MyPageResDTO getInfo(AuthMember member) { + return MemberConverter.toGetInfo(member.getMember()); } @Transactional(readOnly = true) From 3cc1d77b5dd2b7ba9c1eccab6d058917fa6f495c Mon Sep 17 00:00:00 2001 From: 2u6in Date: Sun, 31 May 2026 01:55:59 +0900 Subject: [PATCH 5/8] =?UTF-8?q?refactor:=20=ED=86=A0=ED=81=B0=20=EC=A0=95?= =?UTF-8?q?=EB=B3=B4=EB=A5=BC=20=EC=9D=B4=EC=9A=A9=ED=95=9C=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=EB=A1=9C=20=EB=A6=AC=ED=8C=A9=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/member/controller/MemberController.java | 4 ++-- .../java/umc/domain/member/dto/MemberReqDTO.java | 9 +++++---- .../umc/domain/member/service/MemberService.java | 8 ++------ .../mission/controller/MissionController.java | 8 +++++--- .../umc/domain/mission/service/MissionService.java | 7 +++---- .../domain/review/controller/ReviewController.java | 13 +++++++++---- 6 files changed, 26 insertions(+), 23 deletions(-) diff --git a/src/main/java/umc/domain/member/controller/MemberController.java b/src/main/java/umc/domain/member/controller/MemberController.java index 29dcc6f..b4877be 100644 --- a/src/main/java/umc/domain/member/controller/MemberController.java +++ b/src/main/java/umc/domain/member/controller/MemberController.java @@ -31,9 +31,9 @@ public ApiResponse getInfo( //보유 포인트 조회 @GetMapping("/v1/members/me/points/{memberId}") public ApiResponse getPoint( - @RequestParam(name = "memberId") @Valid Long id + @AuthenticationPrincipal AuthMember member ){ - return ApiResponse.onSuccess(GeneralSuccessCode.OK, memberService.getPoint(id)); + return ApiResponse.onSuccess(GeneralSuccessCode.OK, memberService.getPoint(member)); } //회원 가입 diff --git a/src/main/java/umc/domain/member/dto/MemberReqDTO.java b/src/main/java/umc/domain/member/dto/MemberReqDTO.java index 5b828eb..c7be5b3 100644 --- a/src/main/java/umc/domain/member/dto/MemberReqDTO.java +++ b/src/main/java/umc/domain/member/dto/MemberReqDTO.java @@ -8,10 +8,11 @@ public class MemberReqDTO { - public record MyPageReqDTO( - @NotNull - Long id - ){} + // id를 body로 받아서 조회 할 떄 사용 +// public record MyPageReqDTO( +// @NotNull +// Long id +// ){} public record SignUpReq( @NotBlank diff --git a/src/main/java/umc/domain/member/service/MemberService.java b/src/main/java/umc/domain/member/service/MemberService.java index d94db5c..a15b567 100644 --- a/src/main/java/umc/domain/member/service/MemberService.java +++ b/src/main/java/umc/domain/member/service/MemberService.java @@ -48,12 +48,8 @@ public MemberResDTO.MyPageResDTO getInfo(AuthMember member) { } @Transactional(readOnly = true) - public MemberResDTO.PointResDTO getPoint(Long id) { - Member member = memberRepository.findById(id).orElseThrow( - ()->new MemberException(MemberErrorCode.MEMBER_NOT_FOUND) - ); - - return MemberConverter.toGetPoint(member); + public MemberResDTO.PointResDTO getPoint(AuthMember member) { + return MemberConverter.toGetPoint(member.getMember()); } @Transactional diff --git a/src/main/java/umc/domain/mission/controller/MissionController.java b/src/main/java/umc/domain/mission/controller/MissionController.java index 71e466b..0cce890 100644 --- a/src/main/java/umc/domain/mission/controller/MissionController.java +++ b/src/main/java/umc/domain/mission/controller/MissionController.java @@ -3,6 +3,7 @@ import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; import lombok.RequiredArgsConstructor; +import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import umc.domain.mission.dto.MissionReqDTO; @@ -11,6 +12,7 @@ import umc.domain.mission.service.MissionService; import umc.global.apiPayload.ApiResponse; import umc.global.dto.PageResDTO; +import umc.global.security.entity.AuthMember; @RestController @RequiredArgsConstructor @@ -21,13 +23,13 @@ public class MissionController { @GetMapping("/v1/missions/me/{memberId}") public ApiResponse> getMissions( + @AuthenticationPrincipal AuthMember member, @RequestParam boolean isCompleted, @RequestParam Integer pageSize, @RequestParam Integer pageNumber, - @RequestParam(required = false) String sort, - @PathVariable Long memberId + @RequestParam(required = false) String sort ){ - return ApiResponse.onSuccess(MissionSuccessCode.MISSION_LIST_GET_SUCCESS, missionService.getMissions(memberId, isCompleted, pageSize, pageNumber, sort)); + return ApiResponse.onSuccess(MissionSuccessCode.MISSION_LIST_GET_SUCCESS, missionService.getMissions(member, isCompleted, pageSize, pageNumber, sort)); } @PatchMapping("/v1/missions/{missionId}") diff --git a/src/main/java/umc/domain/mission/service/MissionService.java b/src/main/java/umc/domain/mission/service/MissionService.java index 097e405..14d2953 100644 --- a/src/main/java/umc/domain/mission/service/MissionService.java +++ b/src/main/java/umc/domain/mission/service/MissionService.java @@ -15,6 +15,7 @@ import umc.domain.mission.entity.mapping.MemberMission; import umc.domain.mission.repository.MemberMissionRepository; import umc.global.dto.PageResDTO; +import umc.global.security.entity.AuthMember; @Service @@ -26,7 +27,7 @@ public class MissionService { @Transactional(readOnly = true) public PageResDTO.Pagination getMissions( - Long memberId, + AuthMember authMember, boolean isCompleted, Integer pageSize, Integer pageNumber, @@ -42,9 +43,7 @@ public PageResDTO.Pagination getMissions( PageRequest pageRequest = PageRequest.of(pageNumber, pageSize, sortInfo); - Member member = memberRepository.findById(memberId).orElseThrow( - ()->new MemberException(MemberErrorCode.MEMBER_NOT_FOUND) - ); + Member member = authMember.getMember(); Page missionList = memberMissionRepository.findAllByMemberAndIsCompleted(member, isCompleted, pageRequest); diff --git a/src/main/java/umc/domain/review/controller/ReviewController.java b/src/main/java/umc/domain/review/controller/ReviewController.java index 20a76fb..40f266c 100644 --- a/src/main/java/umc/domain/review/controller/ReviewController.java +++ b/src/main/java/umc/domain/review/controller/ReviewController.java @@ -3,6 +3,7 @@ import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; import lombok.RequiredArgsConstructor; +import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.*; import umc.domain.review.dto.ReviewReqDTO; import umc.domain.review.dto.ReviewResDTO; @@ -11,6 +12,7 @@ import umc.domain.review.service.ReviewService; import umc.global.apiPayload.ApiResponse; import umc.global.dto.CusorResDTO; +import umc.global.security.entity.AuthMember; @RestController @RequiredArgsConstructor @@ -22,18 +24,21 @@ public class ReviewController { //리뷰 작성 @PostMapping("/v1/reviews/{storeId}/{memberId}") public ApiResponse createReview( - @PathVariable @NotNull Long memberId, + @AuthenticationPrincipal AuthMember member, @PathVariable @NotNull Long storeId, @RequestBody @Valid ReviewReqDTO.CreateReviewReq req ){ - return ApiResponse.onSuccess(ReviewSuccessCode.REVIEW_CREATED, reviewService.createReview(memberId, storeId, req)); + return ApiResponse.onSuccess(ReviewSuccessCode.REVIEW_CREATED, reviewService.createReview(member, storeId, req)); } @GetMapping("/v1/reviews") public ApiResponse> getMyReviews( - @RequestBody @Valid ReviewReqDTO.MyReview req + @AuthenticationPrincipal AuthMember member, + @RequestParam(name = "cursor", defaultValue = "-1") String cursor, + @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, + @RequestParam(name = "sortType", defaultValue = "id") String sortType ){ - return ApiResponse.onSuccess(ReviewSuccessCode.REVIEW_FOUND, reviewService.getMyReviews(req)); + return ApiResponse.onSuccess(ReviewSuccessCode.REVIEW_FOUND, reviewService.getMyReviews(member, cursor, pageSize, sortType)); } } From 609e5cd2ce51bee269367074568e395dd0d4c73e Mon Sep 17 00:00:00 2001 From: 2u6in Date: Sun, 31 May 2026 01:58:24 +0900 Subject: [PATCH 6/8] =?UTF-8?q?fix:=20=EB=A6=AC=EB=B7=B0=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=20=EC=BB=A4=EC=84=9C=20=EC=A0=95=EB=B3=B4=20body?= =?UTF-8?q?=EB=A1=9C=20=EB=B0=9B=EB=8A=94=20=EA=B1=B0=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=ED=8C=8C=EB=9D=BC=EB=AF=B8=ED=84=B0=EB=A1=9C=20=EB=B0=9B?= =?UTF-8?q?=EA=B2=8C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../umc/domain/review/dto/ReviewReqDTO.java | 2 -- .../domain/review/service/ReviewService.java | 22 +++++++++---------- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/src/main/java/umc/domain/review/dto/ReviewReqDTO.java b/src/main/java/umc/domain/review/dto/ReviewReqDTO.java index db03492..8dcae57 100644 --- a/src/main/java/umc/domain/review/dto/ReviewReqDTO.java +++ b/src/main/java/umc/domain/review/dto/ReviewReqDTO.java @@ -19,8 +19,6 @@ public record CreateReviewReq( ){} public record MyReview( - @NotNull - Long id, String cursor, Integer pageSize, String sort diff --git a/src/main/java/umc/domain/review/service/ReviewService.java b/src/main/java/umc/domain/review/service/ReviewService.java index 9b42e98..49161c3 100644 --- a/src/main/java/umc/domain/review/service/ReviewService.java +++ b/src/main/java/umc/domain/review/service/ReviewService.java @@ -21,20 +21,18 @@ import umc.domain.store.exception.code.StoreErrorCode; import umc.domain.store.repository.StoreRepository; import umc.global.dto.CusorResDTO; +import umc.global.security.entity.AuthMember; @Service @AllArgsConstructor public class ReviewService { private final ReviewRepository reviewRepository; - private final MemberRepository memberRepository; private final StoreRepository storeRepository; @Transactional - public ReviewResDTO.CreateReviewRes createReview(Long memberId, Long storeId, ReviewReqDTO.CreateReviewReq req) { - Member member = memberRepository.findById(memberId).orElseThrow( - ()->new MemberException(MemberErrorCode.MEMBER_NOT_FOUND) - ); + public ReviewResDTO.CreateReviewRes createReview(AuthMember authMember, Long storeId, ReviewReqDTO.CreateReviewReq req) { + Member member = authMember.getMember(); Store store = storeRepository.findById(storeId).orElseThrow( ()->new StoreException(StoreErrorCode.STORE_NOT_FOUND) @@ -48,23 +46,22 @@ public ReviewResDTO.CreateReviewRes createReview(Long memberId, Long storeId, Re return ReviewConverter.toCreateReviewRes(saved); } - public CusorResDTO.Pagination getMyReviews(ReviewReqDTO.MyReview req) { + public CusorResDTO.Pagination getMyReviews(AuthMember authMember, String cursor, Integer pageSize, String sort) { - PageRequest pageRequest = PageRequest.of(0, req.pageSize()); + PageRequest pageRequest = PageRequest.of(0, pageSize); Slice reviewList; String nextCursor=null; Long idCursor; - Member member = memberRepository.findById(req.id()) - .orElseThrow(() -> new MemberException(MemberErrorCode.MEMBER_NOT_FOUND)); + Member member = authMember.getMember(); - String sortType = req.sort()==null?"id":req.sort().toLowerCase(); + String sortType = sort==null?"id":sort.toLowerCase(); //cursor = id : rating - if (!"-1".equals(req.cursor())) { + if (!"-1".equals(cursor)) { - String[] cursorSplit = req.cursor().split(":"); + String[] cursorSplit = cursor.split(":"); switch (sortType) { @@ -129,4 +126,5 @@ public CusorResDTO.Pagination getMyReviews(ReviewReqDTO. , nextCursor ); } + } From 5fba1d74bf613bdb5eea49705928f93b5e902d92 Mon Sep 17 00:00:00 2001 From: 2u6in Date: Sun, 31 May 2026 02:04:44 +0900 Subject: [PATCH 7/8] =?UTF-8?q?fix:=20url=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/umc/domain/member/controller/MemberController.java | 2 +- .../java/umc/domain/mission/controller/MissionController.java | 4 ++-- .../java/umc/domain/review/controller/ReviewController.java | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/umc/domain/member/controller/MemberController.java b/src/main/java/umc/domain/member/controller/MemberController.java index b4877be..3b49028 100644 --- a/src/main/java/umc/domain/member/controller/MemberController.java +++ b/src/main/java/umc/domain/member/controller/MemberController.java @@ -29,7 +29,7 @@ public ApiResponse getInfo( } //보유 포인트 조회 - @GetMapping("/v1/members/me/points/{memberId}") + @GetMapping("/v1/members/me/points") public ApiResponse getPoint( @AuthenticationPrincipal AuthMember member ){ diff --git a/src/main/java/umc/domain/mission/controller/MissionController.java b/src/main/java/umc/domain/mission/controller/MissionController.java index 0cce890..075e77a 100644 --- a/src/main/java/umc/domain/mission/controller/MissionController.java +++ b/src/main/java/umc/domain/mission/controller/MissionController.java @@ -21,7 +21,7 @@ public class MissionController { private final MissionService missionService; - @GetMapping("/v1/missions/me/{memberId}") + @GetMapping("/v1/missions/me") public ApiResponse> getMissions( @AuthenticationPrincipal AuthMember member, @RequestParam boolean isCompleted, @@ -32,7 +32,7 @@ public ApiResponse> getMissions( return ApiResponse.onSuccess(MissionSuccessCode.MISSION_LIST_GET_SUCCESS, missionService.getMissions(member, isCompleted, pageSize, pageNumber, sort)); } - @PatchMapping("/v1/missions/{missionId}") + @PatchMapping("/v1/missions") public ApiResponse updateMission( @PathVariable @NotNull Long missionId, @RequestBody @Valid MissionReqDTO.MissionStatusUpdate req diff --git a/src/main/java/umc/domain/review/controller/ReviewController.java b/src/main/java/umc/domain/review/controller/ReviewController.java index 40f266c..081ea1d 100644 --- a/src/main/java/umc/domain/review/controller/ReviewController.java +++ b/src/main/java/umc/domain/review/controller/ReviewController.java @@ -22,7 +22,7 @@ public class ReviewController { private final ReviewService reviewService; //리뷰 작성 - @PostMapping("/v1/reviews/{storeId}/{memberId}") + @PostMapping("/v1/reviews/{storeId}") public ApiResponse createReview( @AuthenticationPrincipal AuthMember member, @PathVariable @NotNull Long storeId, From 74a52985adc2b57b130aa5a7908a2125460ac0fb Mon Sep 17 00:00:00 2001 From: 2u6in Date: Sun, 31 May 2026 02:12:32 +0900 Subject: [PATCH 8/8] =?UTF-8?q?refactor:=20jwt=20=ED=86=A0=ED=81=B0?= =?UTF-8?q?=EC=9D=84=20=EC=9D=B4=EC=9A=A9=ED=95=B4=20=ED=99=88=ED=99=94?= =?UTF-8?q?=EB=A9=B4=20=EC=A1=B0=ED=9A=8C=ED=95=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EB=A6=AC=ED=8C=A9=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/home/controller/HomeController.java | 9 +++++---- .../umc/domain/home/service/HomeService.java | 16 +++++----------- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/src/main/java/umc/domain/home/controller/HomeController.java b/src/main/java/umc/domain/home/controller/HomeController.java index 0c6bfa8..d8197ef 100644 --- a/src/main/java/umc/domain/home/controller/HomeController.java +++ b/src/main/java/umc/domain/home/controller/HomeController.java @@ -1,14 +1,15 @@ package umc.domain.home.controller; import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotNull; import lombok.RequiredArgsConstructor; +import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import umc.domain.home.dto.HomeResDTO; import umc.domain.home.service.HomeService; import umc.domain.member.exception.code.MemberSuccessCode; import umc.global.apiPayload.ApiResponse; +import umc.global.security.entity.AuthMember; @RestController @Validated @@ -19,12 +20,12 @@ public class HomeController { private final HomeService homeService; //홈 화면 - @GetMapping("/v1/home/{memberId}") + @GetMapping("/v1/home") public ApiResponse getHome( @RequestParam(name = "region") @NotBlank String region, - @PathVariable @NotNull Long memberId + @AuthenticationPrincipal AuthMember member ){ - return ApiResponse.onSuccess(MemberSuccessCode.HOME_VIEW_SUCCESS, homeService.getHome(memberId, region)); + return ApiResponse.onSuccess(MemberSuccessCode.HOME_VIEW_SUCCESS, homeService.getHome(member, region)); } } diff --git a/src/main/java/umc/domain/home/service/HomeService.java b/src/main/java/umc/domain/home/service/HomeService.java index 7fdf01b..9242292 100644 --- a/src/main/java/umc/domain/home/service/HomeService.java +++ b/src/main/java/umc/domain/home/service/HomeService.java @@ -6,9 +6,7 @@ import umc.domain.home.converter.HomeConverter; import umc.domain.home.dto.HomeResDTO; import umc.domain.member.entity.Member; -import umc.domain.member.exception.MemberException; -import umc.domain.member.exception.code.MemberErrorCode; -import umc.domain.member.repository.MemberRepository; + import umc.domain.mission.entity.Mission; import umc.domain.mission.repository.MemberMissionRepository; import umc.domain.mission.repository.MissionRepository; @@ -16,7 +14,7 @@ import umc.domain.store.exception.StoreException; import umc.domain.store.exception.code.RegionErrorCode; import umc.domain.store.repository.RegionRepository; -import umc.domain.store.repository.StoreRepository; +import umc.global.security.entity.AuthMember; import java.util.List; @@ -24,24 +22,20 @@ @Service public class HomeService { - private final MemberRepository memberRepository; private final MissionRepository missionRepository; - private final StoreRepository storeRepository; private final RegionRepository regionRepository; private final MemberMissionRepository memberMissionRepository; @Transactional(readOnly = true) - public HomeResDTO.HomeDTO getHome(Long memberId, String region) { - Member member = memberRepository.findById(memberId).orElseThrow( - ()->new MemberException(MemberErrorCode.MEMBER_NOT_FOUND) - ); + public HomeResDTO.HomeDTO getHome(AuthMember authMember, String region) { + Member member = authMember.getMember(); Region r = regionRepository.findByName(region).orElseThrow( ()-> new StoreException(RegionErrorCode.REGION_NOT_FOUND) ); Integer missionCount = missionRepository.countByRegion(r); - Integer missionSuccessCount = memberMissionRepository.countCompletedMissionsByRegion(memberId, r); + Integer missionSuccessCount = memberMissionRepository.countCompletedMissionsByRegion(member.getId(), r); List unstartedMissionList = missionRepository.findUnstartedMissions(r); Integer currentPoint = member.getPoint();