diff --git a/src/main/java/org/myteam/server/board/controller/CategoryController.java b/src/main/java/org/myteam/server/board/controller/CategoryController.java index c82d8025..2787666e 100644 --- a/src/main/java/org/myteam/server/board/controller/CategoryController.java +++ b/src/main/java/org/myteam/server/board/controller/CategoryController.java @@ -23,7 +23,6 @@ public class CategoryController { // CREATE: 카테고리 생성 @PostMapping - @PreAuthorize("hasAuthority(T(org.myteam.server.member.domain.MemberRole).ADMIN.name())") public ResponseEntity> createCategory(@Valid @RequestBody CategorySaveRequest categorySaveRequest) { CategoryResponse response = categoryService.create(categorySaveRequest); return ResponseEntity.ok(new ResponseDto<>(SUCCESS.name(), "카테고리 생성 성공", response)); @@ -31,7 +30,6 @@ public ResponseEntity> createCategory(@Valid @Requ // UPDATE: 카테고리 수정 @PutMapping("/{id}") - @PreAuthorize("hasAuthority(T(org.myteam.server.member.domain.MemberRole).ADMIN.name())") public ResponseEntity> updateCategory(@PathVariable Long id, @Valid @RequestBody CategoryUpdateRequest categoryUpdateRequest) { CategoryResponse response = categoryService.update(id, categoryUpdateRequest); @@ -40,7 +38,6 @@ public ResponseEntity> updateCategory(@PathVariabl // DELETE: 카테고리 삭제 @DeleteMapping("/{id}") - @PreAuthorize("hasAuthority(T(org.myteam.server.member.domain.MemberRole).ADMIN.name())") public ResponseEntity> deleteCategory(@PathVariable Long id) { categoryService.delete(id); return ResponseEntity.ok(new ResponseDto<>(SUCCESS.name(), "카테고리 삭제 성공", null)); diff --git a/src/main/java/org/myteam/server/global/security/config/SecurityConfig.java b/src/main/java/org/myteam/server/global/security/config/SecurityConfig.java index 3fe19066..71843dc3 100644 --- a/src/main/java/org/myteam/server/global/security/config/SecurityConfig.java +++ b/src/main/java/org/myteam/server/global/security/config/SecurityConfig.java @@ -17,6 +17,7 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpMethod; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.ProviderManager; import org.springframework.security.authentication.dao.DaoAuthenticationProvider; @@ -97,14 +98,14 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti ); http - .addFilterBefore( + .addFilterAt( + new JwtAuthenticationFilter(authenticationManager(), jwtProvider, refreshJpaRepository), + UsernamePasswordAuthenticationFilter.class + ) // 로그인 인증 필터 + .addFilterAfter( new TokenAuthenticationFilter(jwtProvider), JwtAuthenticationFilter.class - ) - .addFilterAfter( - new JwtAuthenticationFilter(authenticationManager(), jwtProvider, refreshJpaRepository), - TokenAuthenticationFilter.class - ); // 회원 로그인 필터 + ); // JWT 토큰 검증 필터 // cors 설정 http @@ -113,13 +114,24 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti // 경로별 인가 작업 http .authorizeHttpRequests(authorizeRequests -> - authorizeRequests - .requestMatchers("/h2-console").permitAll() // H2 콘솔 접근 허용 - .requestMatchers(TOKEN_REISSUE_PATH).permitAll() // 토큰 재발급 - .requestMatchers("/api/admin/**").hasAnyRole(MemberRole.ADMIN.name()) - .requestMatchers("/api/members/role").permitAll() // 유저 권한 변경 허용 - .requestMatchers("/api/members/get-token/{email}").permitAll() // 테스트용 토큰 발급용 - .anyRequest().permitAll() // 나머지 요청은 모두 허용 + authorizeRequests + .requestMatchers("/upload/**").permitAll() // 정적 자원 접근 허용 + .requestMatchers("/v3/api-docs/**", "/swagger-ui/**", "/swagger-resources/**").permitAll() + + .requestMatchers("/h2-console").permitAll() // H2 콘솔 접근 허용 + .requestMatchers("/api/members/get-token/**").permitAll() // 테스트용 토큰 발급용 + + .requestMatchers("/api/admin/**").hasAnyAuthority(MemberRole.ADMIN.name()) + .requestMatchers(HttpMethod.POST, "/api/me/create").permitAll() + .requestMatchers(HttpMethod.GET, "/api/categories/**").permitAll() + .requestMatchers(HttpMethod.PUT, "/api/categories/**").hasAnyAuthority(MemberRole.ADMIN.name()) + .requestMatchers(HttpMethod.DELETE, "/api/categories/**").hasAnyAuthority(MemberRole.ADMIN.name()) + .requestMatchers(HttpMethod.POST, "/api/categories").hasAnyAuthority(MemberRole.ADMIN.name()) + + .requestMatchers(TOKEN_REISSUE_PATH).permitAll() // 토큰 재발급 + .requestMatchers("/api/members/role").permitAll() // 유저 권한 변경 허용 + + .anyRequest().authenticated() // 나머지 요청은 모두 허용 ); http diff --git a/src/main/java/org/myteam/server/global/security/filter/JwtAuthenticationFilter.java b/src/main/java/org/myteam/server/global/security/filter/JwtAuthenticationFilter.java index 30c96691..ff66608b 100644 --- a/src/main/java/org/myteam/server/global/security/filter/JwtAuthenticationFilter.java +++ b/src/main/java/org/myteam/server/global/security/filter/JwtAuthenticationFilter.java @@ -85,7 +85,7 @@ protected void successfulAuthentication(HttpServletRequest request, HttpServletR if (status.equals(PENDING.name())) { log.warn("PENDING 상태인 경우 로그인이 불가능합니다"); - sendErrorResponse(response, HttpStatus.FORBIDDEN, "PENDING 상태인 경우 로그인이 불가능합니다"); + sendErrorResponse(response, HttpStatus.LOCKED, "PENDING 상태인 경우 로그인이 불가능합니다"); return; } else if (status.equals(INACTIVE.name())) { log.warn("INACTIVE 상태인 경우 로그인이 불가능합니다"); @@ -113,6 +113,7 @@ protected void successfulAuthentication(HttpServletRequest request, HttpServletR log.debug("print accessToken: {}", accessToken); log.debug("print refreshToken: {}", refreshToken); + log.debug("print role: {}", role); //Refresh 토큰 저장 addRefreshEntity(publicId, refreshToken, Duration.ofHours(24)); @@ -122,7 +123,6 @@ protected void successfulAuthentication(HttpServletRequest request, HttpServletR response.addCookie(createCookie(REFRESH_TOKEN_KEY, cookieValue, LOGOUT_PATH, 24 * 60 * 60, true)); response.setStatus(HttpStatus.OK.value()); - // frontUrl += "?" + ACCESS_TOKEN_KEY + "=" + ("Bearer%20" + accessToken); // frontUrl += "&" + REFRESH_TOKEN_KEY + "=" + ("Bearer%20" + refreshToken); // response.sendRedirect(frontUrl); diff --git a/src/main/java/org/myteam/server/global/security/filter/TokenAuthenticationFilter.java b/src/main/java/org/myteam/server/global/security/filter/TokenAuthenticationFilter.java index a1a6317c..786ab874 100644 --- a/src/main/java/org/myteam/server/global/security/filter/TokenAuthenticationFilter.java +++ b/src/main/java/org/myteam/server/global/security/filter/TokenAuthenticationFilter.java @@ -34,24 +34,26 @@ public class TokenAuthenticationFilter extends OncePerRequestFilter { @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { - log.info("TokenAuthenticationFilter 토큰을 검사중"); + log.info("Token Authenticate Filter 토큰을 검사중"); String authorizationHeader = request.getHeader(HEADER_AUTHORIZATION); String accessToken = jwtProvider.getAccessToken(authorizationHeader); log.info("accessToken : " + accessToken); if (StringUtils.isNotBlank(accessToken)) { - if (jwtProvider.validToken(accessToken)) { + try { + if (!jwtProvider.validToken(accessToken)) { + log.warn("인증되지 않은 토큰입니다"); + filterChain.doFilter(request, response); + return; + } String accessCategory = jwtProvider.getCategory(accessToken); - - if (!accessCategory.equals(TOKEN_CATEGORY_ACCESS)) { - // RestControllerAdvice 로 에러가 전달 되지 않아 여기서 에러 처리함 - log.warn("잘못된 토큰 유형입니다."); - sendErrorResponse(response, INVALID_TOKEN_TYPE.getStatus(), "잘못된 토큰 유형"); + if (!TOKEN_CATEGORY_ACCESS.equals(accessCategory)) { + log.warn("잘못된 토큰 유형입니다"); + filterChain.doFilter(request, response); return; } - // 토큰에서 username과 role 획득 UUID publicId = jwtProvider.getPublicId(accessToken); String role = jwtProvider.getRole(accessToken); String status = jwtProvider.getStatus(accessToken); @@ -60,7 +62,6 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse log.info("role : " + role); log.info("status : " + status); - // Member 를 생성하여 값 set Member member = Member.builder() .publicId(publicId) .role(MemberRole.valueOf(role)) @@ -68,45 +69,16 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse .build(); CustomUserDetails customUserDetails = new CustomUserDetails(member); - Authentication authToken = new UsernamePasswordAuthenticationToken(customUserDetails, null, customUserDetails.getAuthorities()); + SecurityContextHolder.getContext().setAuthentication(authToken); - log.info("security Context 에 정보 저장이 완료되었습니다."); - } else { - try { - if (jwtProvider.isExpired(accessToken)) { - // RestControllerAdvice 로 에러가 전달 되지 않아 여기서 에러 처리함 - log.warn("토큰이 만료되었습니다."); - sendErrorResponse(response, ACCESS_TOKEN_EXPIRED.getStatus(), "만료된 토큰"); - return; - } - } catch (JwtException | IllegalArgumentException e) { - // RestControllerAdvice 로 에러가 전달 되지 않아 여기서 에러 처리함 - log.error("잘못된 JWT 토큰 형식 또는 그 외 에러 : {}", e.getMessage()); - sendErrorResponse(response, INVALID_ACCESS_TOKEN.getStatus(), "잘못된 JWT 토큰 형식 또는 그 외 에러"); - return; - } - // RestControllerAdvice 로 에러가 전달 되지 않아 여기서 에러 처리함 - log.warn("인증되지 않은 토큰입니다."); - sendErrorResponse(response, INVALID_ACCESS_TOKEN.getStatus(), "인증되지 않은 토큰"); + log.info("SecurityContext 에 인증 정보 저장 완료"); + } catch (JwtException e) { + log.error("JWT 처리 중 오류 발생: {}", e.getMessage()); + filterChain.doFilter(request, response); return; } } filterChain.doFilter(request, response); } - - /** - * 공통 에러 응답 처리 메서드 - * - * @param response HttpServletResponse - * @param httpStatus HTTP 상태 오브젝트 - * @param message 메시지 - * @throws IOException - */ - private void sendErrorResponse(HttpServletResponse response, HttpStatus httpStatus, String message) throws IOException { - response.setStatus(httpStatus.value()); - response.setContentType("application/json"); - response.setCharacterEncoding("UTF-8"); - response.getWriter().write(String.format("{\"message\":\"%s\",\"status\":\"%s\"}", message, httpStatus.name())); - } } diff --git a/src/main/java/org/myteam/server/member/controller/MemberController.java b/src/main/java/org/myteam/server/member/controller/MemberController.java index 442ea2a9..f7716543 100644 --- a/src/main/java/org/myteam/server/member/controller/MemberController.java +++ b/src/main/java/org/myteam/server/member/controller/MemberController.java @@ -66,11 +66,9 @@ public ResponseEntity updateStatus(@RequestBody @Valid MemberStatusUpdateRequ log.info("email : {}" , response.getEmail()); // 서비스 호출 - MemberStatus memberStatus = memberStatusUpdateRequest.getStatus(); // 변경 상태 - String targetEmail = response.getEmail(); // 상태를 변경할 대상 이메일 - String extractedEmail = memberStatusUpdateRequest.getEmail(); // 토큰에서 추출된 이메일 + String targetEmail = response.getEmail(); // 변경을 시도하는 유저의 이메일 (본인 또는 관리자) - memberService.updateStatus(extractedEmail, targetEmail, memberStatus); + memberService.updateStatus(targetEmail, memberStatusUpdateRequest); return ResponseEntity.ok(new ResponseDto<>(SUCCESS.name(), "회원 상태가 성공적으로 변경되었습니다.", null)); } @@ -82,11 +80,19 @@ public ResponseEntity updateRole(@RequestBody @Valid MemberRoleUpdateRequest return new ResponseEntity<>(new ResponseDto<>(SUCCESS.name(), "권한 변경 성공", response), HttpStatus.OK); } - @GetMapping("/get-token/{email}") + @GetMapping("/get-token/admin/{email}") + public ResponseEntity getAdminToken(@PathVariable String email) { + log.info("getToken 메서드가 실행되었습니다."); + MemberResponse response = memberService.getByEmail(email); + String encode = TOKEN_PREFIX + jwtProvider.generateToken(TOKEN_CATEGORY_ACCESS, Duration.ofHours(10), response.getPublicId(), MemberRole.ADMIN.name(), response.getStatus().name()); + return new ResponseEntity<>(new ResponseDto<>(SUCCESS.name(), "토큰 조회 성공", encode), HttpStatus.OK); + } + + @GetMapping("/get-token/user/{email}") public ResponseEntity getToken(@PathVariable String email) { log.info("getToken 메서드가 실행되었습니다."); MemberResponse response = memberService.getByEmail(email); - String encode = TOKEN_PREFIX + jwtProvider.generateToken(TOKEN_CATEGORY_ACCESS, Duration.ofHours(6), response.getPublicId(), MemberRole.USER.name(), response.getStatus().name()); + String encode = TOKEN_PREFIX + jwtProvider.generateToken(TOKEN_CATEGORY_ACCESS, Duration.ofHours(10), response.getPublicId(), MemberRole.USER.name(), response.getStatus().name()); return new ResponseEntity<>(new ResponseDto<>(SUCCESS.name(), "토큰 조회 성공", encode), HttpStatus.OK); } } diff --git a/src/main/java/org/myteam/server/member/domain/GenderType.java b/src/main/java/org/myteam/server/member/domain/GenderType.java index afe02e52..f52d8eb4 100644 --- a/src/main/java/org/myteam/server/member/domain/GenderType.java +++ b/src/main/java/org/myteam/server/member/domain/GenderType.java @@ -2,9 +2,6 @@ import lombok.AllArgsConstructor; import lombok.Getter; -import org.myteam.server.global.exception.PlayHiveException; - -import static org.myteam.server.global.exception.ErrorCode.INVALID_PARAMETER; @AllArgsConstructor @Getter @@ -18,6 +15,6 @@ public static GenderType fromValue(String value) { return gender; } } - throw new PlayHiveException(INVALID_PARAMETER, "Invalid gender value: " + value); + return null; } } diff --git a/src/main/java/org/myteam/server/member/dto/MemberDeleteRequest.java b/src/main/java/org/myteam/server/member/dto/MemberDeleteRequest.java index 1cade623..dc783bb6 100644 --- a/src/main/java/org/myteam/server/member/dto/MemberDeleteRequest.java +++ b/src/main/java/org/myteam/server/member/dto/MemberDeleteRequest.java @@ -14,6 +14,6 @@ public class MemberDeleteRequest { @NotBlank // @Pattern(regexp = "^(?=.*[a-zA-Z])(?=.*[!@#$%^*+=-])(?=.*[0-9]).{8,15}$", message = "비밀번호는 영문+숫자 조합 4 ~ 10자 이내로 입력해주세요") - @Pattern(regexp = "^(?=.*[a-zA-Z])(?=.*[0-9]).{8,15}$", message = "비밀번호는 영문, 숫자 조합 4 ~ 10자 이내로 입력해주세요") + @Pattern(regexp = "^(?=.*[a-zA-Z])(?=.*[0-9]).{4,15}$", message = "비밀번호는 영문, 숫자 조합 4 ~ 15자 이내로 입력해주세요") private String password; // 비밀번호 } diff --git a/src/main/java/org/myteam/server/member/dto/MemberSaveRequest.java b/src/main/java/org/myteam/server/member/dto/MemberSaveRequest.java index 267a87db..ce86271d 100644 --- a/src/main/java/org/myteam/server/member/dto/MemberSaveRequest.java +++ b/src/main/java/org/myteam/server/member/dto/MemberSaveRequest.java @@ -17,7 +17,7 @@ public class MemberSaveRequest { @NotBlank // @Pattern(regexp = "^(?=.*[a-zA-Z])(?=.*[!@#$%^*+=-])(?=.*[0-9]).{8,15}$", message = "비밀번호는 영문+숫자 조합 4 ~ 10자 이내로 입력해주세요") - @Pattern(regexp = "^(?=.*[a-zA-Z])(?=.*[0-9]).{8,15}$", message = "비밀번호는 영문, 숫자 조합 4 ~ 10자 이내로 입력해주세요") + @Pattern(regexp = "^(?=.*[a-zA-Z])(?=.*[0-9]).{4,15}$", message = "비밀번호는 영문, 숫자 조합 4 ~ 15자 이내로 입력해주세요") private String password; // 비밀번호 @NotBlank diff --git a/src/main/java/org/myteam/server/member/dto/MemberUpdateRequest.java b/src/main/java/org/myteam/server/member/dto/MemberUpdateRequest.java index b008ccbf..bd870372 100644 --- a/src/main/java/org/myteam/server/member/dto/MemberUpdateRequest.java +++ b/src/main/java/org/myteam/server/member/dto/MemberUpdateRequest.java @@ -30,7 +30,7 @@ public class MemberUpdateRequest { @Column(name = "birth_date") private LocalDate birthdate; - @Pattern(regexp = "^(MALE|FEMALE)$", message = "성별은 MALE, FEMALE 중 하나여야 합니다.") + @Pattern(regexp = "^(?i)(MALE|FEMALE)$", message = "성별은 MALE, FEMALE 중 하나여야 합니다.") private String gender; private MemberStatus status; diff --git a/src/main/java/org/myteam/server/member/dto/PasswordChangeRequest.java b/src/main/java/org/myteam/server/member/dto/PasswordChangeRequest.java index 24b8f77e..40d84dba 100644 --- a/src/main/java/org/myteam/server/member/dto/PasswordChangeRequest.java +++ b/src/main/java/org/myteam/server/member/dto/PasswordChangeRequest.java @@ -8,15 +8,15 @@ @NoArgsConstructor public class PasswordChangeRequest { @NotNull - @Pattern(regexp = "^(?=.*[a-zA-Z])(?=.*[0-9]).{8,15}$", message = "비밀번호는 영문, 숫자 조합 4 ~ 10자 이내로 입력해주세요") + @Pattern(regexp = "^(?=.*[a-zA-Z])(?=.*[0-9]).{4,15}$", message = "비밀번호는 영문, 숫자 조합 4 ~ 15자 이내로 입력해주세요") private String password; @NotNull - @Pattern(regexp = "^(?=.*[a-zA-Z])(?=.*[0-9]).{8,15}$", message = "비밀번호는 영문, 숫자 조합 4 ~ 10자 이내로 입력해주세요") + @Pattern(regexp = "^(?=.*[a-zA-Z])(?=.*[0-9]).{4,15}$", message = "비밀번호는 영문, 숫자 조합 4 ~ 15자 이내로 입력해주세요") private String newPassword; @NotNull - @Pattern(regexp = "^(?=.*[a-zA-Z])(?=.*[0-9]).{8,15}$", message = "비밀번호는 영문, 숫자 조합 4 ~ 10자 이내로 입력해주세요") + @Pattern(regexp = "^(?=.*[a-zA-Z])(?=.*[0-9]).{4,15}$", message = "비밀번호는 영문, 숫자 조합 4 ~ 15자 이내로 입력해주세요") private String confirmPassword; @Builder diff --git a/src/main/java/org/myteam/server/member/entity/Member.java b/src/main/java/org/myteam/server/member/entity/Member.java index 671175f3..84fdc638 100644 --- a/src/main/java/org/myteam/server/member/entity/Member.java +++ b/src/main/java/org/myteam/server/member/entity/Member.java @@ -16,6 +16,7 @@ import org.myteam.server.member.dto.PasswordChangeRequest; import org.springframework.security.crypto.password.PasswordEncoder; +import static org.myteam.server.member.domain.MemberRole.ADMIN; import static org.myteam.server.member.domain.MemberRole.USER; import static org.myteam.server.member.domain.MemberStatus.PENDING; import static org.myteam.server.member.domain.MemberType.LOCAL; @@ -126,6 +127,10 @@ public boolean verifyOwnEmail(String email) { return email.equals(this.email); } + public boolean isAdmin() { + return this.role.equals(ADMIN); + } + public boolean validatePassword(String inputPassword, PasswordEncoder bCryptPasswordEncoder) { // 입력된 평문 패스워드와 이미 암호화된 패스워드를 비교 boolean isValid = bCryptPasswordEncoder.matches(inputPassword, this.password); diff --git a/src/main/java/org/myteam/server/member/service/MemberService.java b/src/main/java/org/myteam/server/member/service/MemberService.java index 46fd5abf..cdeb0daa 100644 --- a/src/main/java/org/myteam/server/member/service/MemberService.java +++ b/src/main/java/org/myteam/server/member/service/MemberService.java @@ -5,12 +5,10 @@ import org.myteam.server.global.exception.ErrorCode; import org.myteam.server.global.exception.PlayHiveException; import org.myteam.server.global.security.jwt.JwtProvider; +import org.myteam.server.member.domain.MemberRole; import org.myteam.server.member.domain.MemberStatus; -import org.myteam.server.member.dto.MemberSaveRequest; +import org.myteam.server.member.dto.*; import org.myteam.server.member.controller.response.MemberResponse; -import org.myteam.server.member.dto.MemberRoleUpdateRequest; -import org.myteam.server.member.dto.MemberUpdateRequest; -import org.myteam.server.member.dto.PasswordChangeRequest; import org.myteam.server.member.entity.Member; import org.myteam.server.member.repository.MemberJpaRepository; import org.myteam.server.member.repository.MemberRepository; @@ -169,18 +167,31 @@ public void changePassword(String email, PasswordChangeRequest passwordChangeReq } @Transactional - public void updateStatus(String extractedEmail, String targetEmail, MemberStatus memberStatus) { - log.info("토큰에서 추출된 이메일: {}, 상태를 변경할 대상 이메일: {}, 새로운 상태: {}", extractedEmail, targetEmail, memberStatus); - - Member member = memberRepository.getByEmail(targetEmail); + public void updateStatus(String targetEmail, MemberStatusUpdateRequest memberStatusUpdateRequest) { + log.info("토큰에서 추출된 이메일: {}, 상태를 변경할 대상 이메일: {}, 새로운 상태: {}", + targetEmail, memberStatusUpdateRequest.getEmail(), memberStatusUpdateRequest.getStatus().name()); + + // 요청자와 대상 사용자 정보 조회 + Member requester = memberRepository.getByEmail(targetEmail); // 요청자 + Member targetMember = memberRepository.getByEmail(memberStatusUpdateRequest.getEmail()); // 상태 변경 대상자 + + // 1. 요청자가 본인의 상태를 변경하려는 경우 + if (requester.verifyOwnEmail(memberStatusUpdateRequest.getEmail())) { + log.info("사용자가 자신의 상태를 변경 중: {}", targetEmail); + requester.updateStatus(memberStatusUpdateRequest.getStatus()); + return; + } - // 자신의 계정이 아닌 다른 계정을 수정하려고 함 - if (!member.verifyOwnEmail(extractedEmail)) { - throw new PlayHiveException(NO_PERMISSION); + // 2. 관리자가 다른 사용자의 상태를 변경하려는 경우 + if (requester.isAdmin()) { + log.info("관리자가 상태를 변경 중: {}, 대상자: {}", targetEmail, memberStatusUpdateRequest.getEmail()); + targetMember.updateStatus(memberStatusUpdateRequest.getStatus()); + return; } - // 상태 업데이트 - member.updateStatus(memberStatus); + // 3. 권한 없는 사용자가 다른 사용자의 상태를 변경하려고 시도한 경우 + log.warn("권한 없는 요청: 요청자 {}, 대상자 {}", targetEmail, memberStatusUpdateRequest.getEmail()); + throw new PlayHiveException(NO_PERMISSION, "상태 수정 권한이 없습니다."); } public boolean existsByEmail(String email) { diff --git a/src/main/java/org/myteam/server/oauth2/handler/CustomOauth2SuccessHandler.java b/src/main/java/org/myteam/server/oauth2/handler/CustomOauth2SuccessHandler.java index 3fe234b2..cac3e927 100644 --- a/src/main/java/org/myteam/server/oauth2/handler/CustomOauth2SuccessHandler.java +++ b/src/main/java/org/myteam/server/oauth2/handler/CustomOauth2SuccessHandler.java @@ -54,9 +54,26 @@ public void onAuthenticationSuccess(HttpServletRequest request, HttpServletRespo String role = auth.getAuthority(); String status = customUserDetails.getStatus().name(); + log.info("onAuthenticationSuccess email: {}", email); + log.info("onAuthenticationSuccess role: {}", role); + //유저확인 + Member member = memberJpaRepository.findByEmail(email) + .orElseThrow(() -> new RuntimeException("Member not found")); + log.info("onAuthenticationSuccess publicId: {}", member.getPublicId()); + log.info("onAuthenticationSuccess role: {}", member.getRole()); + + if (status.equals(PENDING.name())) { log.warn("PENDING 상태인 경우 로그인이 불가능합니다"); // sendErrorResponse(response, HttpStatus.FORBIDDEN, "PENDING 상태인 경우 로그인이 불가능합니다"); + // X-Refresh-Token + String refreshToken = jwtProvider.generateToken(TOKEN_CATEGORY_REFRESH, Duration.ofDays(7), member.getPublicId(), member.getRole().name(), member.getStatus().name()); + String cookieValue = URLEncoder.encode("Bearer " + refreshToken, StandardCharsets.UTF_8); + + // redirect 순간 Header 값 날아감 + // response.addHeader(ACCESS_TOKEN_KEY, "Bearer " + accessToken); + response.addCookie(createCookie(REFRESH_TOKEN_KEY, cookieValue, TOKEN_REISSUE_PATH, 24 * 60 * 60, true)); + response.addCookie(createCookie(REFRESH_TOKEN_KEY, cookieValue, LOGOUT_PATH, 24 * 60 * 60, true)); response.sendRedirect(frontUrl + "?status=" + status); return; } else if (status.equals(INACTIVE.name())) { @@ -71,13 +88,6 @@ public void onAuthenticationSuccess(HttpServletRequest request, HttpServletRespo return; } - log.info("onAuthenticationSuccess email: {}", email); - log.info("onAuthenticationSuccess role: {}", role); - //유저확인 - Member member = memberJpaRepository.findByEmail(email) - .orElseThrow(() -> new RuntimeException("Member not found")); - log.info("onAuthenticationSuccess publicId: {}", member.getPublicId()); - log.info("onAuthenticationSuccess role: {}", member.getRole()); // Authorization String accessToken = jwtProvider.generateToken(TOKEN_CATEGORY_ACCESS, Duration.ofHours(1), member.getPublicId(), member.getRole().name(), member.getStatus().name()); // X-Refresh-Token