From 2cbc87d8fcd1731c895cb4a8864160a605fb784b Mon Sep 17 00:00:00 2001 From: Jaehyun Ahn <91878695+uwoobeat@users.noreply.github.com> Date: Wed, 28 Feb 2024 20:58:52 +0900 Subject: [PATCH 1/6] =?UTF-8?q?hotfix:=20=EC=9D=B4=EB=A9=94=EC=9D=BC=20?= =?UTF-8?q?=EC=A0=95=EA=B7=9C=EC=8B=9D=EC=97=90=20=EC=96=B8=EB=8D=94?= =?UTF-8?q?=EC=8A=A4=EC=BD=94=EC=96=B4=EB=A5=BC=20=ED=97=88=EC=9A=A9?= =?UTF-8?q?=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95=20(#206)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: 언더스코어 허용하도록 변경 * refactor: 테스트 접근제어자 제거 --------- Co-authored-by: Cho Sangwook <82208159+Sangwook02@users.noreply.github.com> --- .../global/common/constant/RegexConstant.java | 3 +-- .../email/HongikUnivEmailValidatorTest.java | 15 +++++++-------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/gdschongik/gdsc/global/common/constant/RegexConstant.java b/src/main/java/com/gdschongik/gdsc/global/common/constant/RegexConstant.java index d557d610d..0ca98289b 100644 --- a/src/main/java/com/gdschongik/gdsc/global/common/constant/RegexConstant.java +++ b/src/main/java/com/gdschongik/gdsc/global/common/constant/RegexConstant.java @@ -7,8 +7,7 @@ public class RegexConstant { public static final String PHONE_WITHOUT_HYPHEN = "^010[0-9]{8}$"; public static final String NICKNAME = "[ㄱ-ㅣ가-힣]{1,6}$"; public static final String DEPARTMENT = "^D[0-9]{3}$"; - - public static final String HONGIK_EMAIL = "^[^\\W&=_'-+,<>]+(\\.[^\\W&=_'-+,<>]+)*@g\\.hongik\\.ac\\.kr$"; + public static final String HONGIK_EMAIL = "^[^\\W&=+'-+,<>]+(\\.[^\\W&=+'-+,<>]+)*@g\\.hongik\\.ac\\.kr$"; private RegexConstant() {} } diff --git a/src/test/java/com/gdschongik/gdsc/domain/email/HongikUnivEmailValidatorTest.java b/src/test/java/com/gdschongik/gdsc/domain/email/HongikUnivEmailValidatorTest.java index 05bbcf978..ec99cc414 100644 --- a/src/test/java/com/gdschongik/gdsc/domain/email/HongikUnivEmailValidatorTest.java +++ b/src/test/java/com/gdschongik/gdsc/domain/email/HongikUnivEmailValidatorTest.java @@ -16,14 +16,14 @@ @SpringBootTest @ActiveProfiles("test") -public class HongikUnivEmailValidatorTest { +class HongikUnivEmailValidatorTest { @Autowired private HongikUnivEmailValidator hongikUnivEmailValidator; @Test @DisplayName("'g.hongik.ac.kr' 도메인을 가진 이메일을 검증할 수 있다.") - public void validateEmailDomainTest() { + void validateEmailDomainTest() { String hongikDomainEmail = "test@g.hongik.ac.kr"; assertThatCode(() -> hongikUnivEmailValidator.validate(hongikDomainEmail)) @@ -33,7 +33,7 @@ public void validateEmailDomainTest() { @ParameterizedTest @ValueSource(strings = {"test@naver.com", "test@mail.hongik.ac.kr", "test@gmail.com", "test@gg.hongik.ac.kr"}) @DisplayName("'g.hongik.ac.kr'가 아닌 도메인을 가진 이메일을 입력하면 예외를 발생시킨다.") - public void validateEmailDomainMismatchTest(String email) { + void validateEmailDomainMismatchTest(String email) { assertThatThrownBy(() -> hongikUnivEmailValidator.validate(email)) .isInstanceOf(CustomException.class) .hasMessage(ErrorCode.UNIV_EMAIL_DOMAIN_MISMATCH.getMessage()); @@ -41,7 +41,7 @@ public void validateEmailDomainMismatchTest(String email) { @Test @DisplayName("Email의 '@' 앞 부분에는 연속되지 않은 점이 포함될 수 있다.") - public void validateEmailFormatWithDotsTest() { + void validateEmailFormatWithDotsTest() { String email = "t.e.s.t@g.hongik.ac.kr"; assertThatCode(() -> hongikUnivEmailValidator.validate(email)).doesNotThrowAnyException(); @@ -52,7 +52,6 @@ public void validateEmailFormatWithDotsTest() { strings = { "te&st@g.hongik.ac.kr", "te=st@g.hongik.ac.kr", - "te_st@g.hongik.ac.kr", "te'st@g.hongik.ac.kr", "te-st@g.hongik.ac.kr", "te+st@g.hongik.ac.kr", @@ -60,8 +59,8 @@ public void validateEmailFormatWithDotsTest() { "test@g.hongik.ac.kr" }) - @DisplayName("Email의 '@' 앞 부분에 '&', '=', '_', ''', '-', '+', ',', '<', '>'가 포함되는 경우 예외를 발생시킨다.") - public void validateEmailFormatMismatchTest(String email) { + @DisplayName("Email의 '@' 앞 부분에 '&', '=', ''', '-', '+', ',', '<', '>'가 포함되는 경우 예외를 발생시킨다.") + void validateEmailFormatMismatchTest(String email) { assertThatThrownBy(() -> hongikUnivEmailValidator.validate(email)) .isInstanceOf(CustomException.class) .hasMessage(ErrorCode.UNIV_EMAIL_FORMAT_MISMATCH.getMessage()); @@ -69,7 +68,7 @@ public void validateEmailFormatMismatchTest(String email) { @Test @DisplayName("Email의 '@' 앞 부분에 '.'이 2개 연속 오는 경우 예외를 발생시킨다.") - public void validateEmailFormatMismatchWithDotsTest() { + void validateEmailFormatMismatchWithDotsTest() { String email = "te..st@g.hongik.ac.kr"; assertThatThrownBy(() -> hongikUnivEmailValidator.validate(email)) .isInstanceOf(CustomException.class) From ba32f454c8cde12337c447e1a14a8ef54f62b541 Mon Sep 17 00:00:00 2001 From: Cho Sangwook <82208159+Sangwook02@users.noreply.github.com> Date: Thu, 29 Feb 2024 00:28:42 +0900 Subject: [PATCH 2/6] =?UTF-8?q?chore:=20=ED=81=B4=EB=9D=BC=EC=9D=B4?= =?UTF-8?q?=EC=96=B8=ED=8A=B8=20=EC=96=B4=EB=93=9C=EB=AF=BC=20URL=EC=97=90?= =?UTF-8?q?=20=EB=8C=80=ED=95=9C=20CORS=20=EC=84=A4=EC=A0=95=20(#208)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit chore: 클라이언트 어드민 url에 대한 cors 설정 --- .../gdsc/global/common/constant/UrlConstant.java | 6 ++++-- .../gdschongik/gdsc/global/config/WebSecurityConfig.java | 6 ++++-- .../gdsc/global/security/CustomSuccessHandler.java | 2 +- .../gdsc/global/util/email/VerificationLinkUtil.java | 8 ++++---- 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/gdschongik/gdsc/global/common/constant/UrlConstant.java b/src/main/java/com/gdschongik/gdsc/global/common/constant/UrlConstant.java index d824dfeb2..a54bd8eda 100644 --- a/src/main/java/com/gdschongik/gdsc/global/common/constant/UrlConstant.java +++ b/src/main/java/com/gdschongik/gdsc/global/common/constant/UrlConstant.java @@ -6,8 +6,10 @@ public class UrlConstant { private UrlConstant() {} - public static final String PROD_CLIENT_URL = "https://onboarding.gdschongik.com"; - public static final String DEV_CLIENT_URL = "https://dev-onboarding.gdschongik.com"; + public static final String PROD_CLIENT_ONBOARDING_URL = "https://onboarding.gdschongik.com"; + public static final String PROD_CLIENT_ADMIN_URL = "https://admin.gdschongik.com"; + public static final String DEV_CLIENT_ONBOARDING_URL = "https://dev-onboarding.gdschongik.com"; + public static final String DEV_CLIENT_ADMIN_URL = "https://dev-admin.gdschongik.com"; public static final String LOCAL_REACT_CLIENT_URL = "http://localhost:3000"; public static final String LOCAL_REACT_CLIENT_SECURE_URL = "https://localhost:3000"; public static final String LOCAL_VITE_CLIENT_URL = "http://localhost:5173"; diff --git a/src/main/java/com/gdschongik/gdsc/global/config/WebSecurityConfig.java b/src/main/java/com/gdschongik/gdsc/global/config/WebSecurityConfig.java index 6790053f6..b22ac5abb 100644 --- a/src/main/java/com/gdschongik/gdsc/global/config/WebSecurityConfig.java +++ b/src/main/java/com/gdschongik/gdsc/global/config/WebSecurityConfig.java @@ -146,11 +146,13 @@ public CorsConfigurationSource corsConfigurationSource() { CorsConfiguration configuration = new CorsConfiguration(); if (environmentUtil.isProdProfile()) { - configuration.addAllowedOriginPattern(PROD_CLIENT_URL); + configuration.addAllowedOriginPattern(PROD_CLIENT_ONBOARDING_URL); + configuration.addAllowedOriginPattern(PROD_CLIENT_ADMIN_URL); } if (environmentUtil.isDevProfile()) { - configuration.addAllowedOriginPattern(DEV_CLIENT_URL); + configuration.addAllowedOriginPattern(DEV_CLIENT_ONBOARDING_URL); + configuration.addAllowedOriginPattern(DEV_CLIENT_ADMIN_URL); configuration.addAllowedOriginPattern(LOCAL_REACT_CLIENT_URL); configuration.addAllowedOriginPattern(LOCAL_REACT_CLIENT_SECURE_URL); configuration.addAllowedOriginPattern(LOCAL_VITE_CLIENT_URL); diff --git a/src/main/java/com/gdschongik/gdsc/global/security/CustomSuccessHandler.java b/src/main/java/com/gdschongik/gdsc/global/security/CustomSuccessHandler.java index 8e65eadd7..a2275c441 100644 --- a/src/main/java/com/gdschongik/gdsc/global/security/CustomSuccessHandler.java +++ b/src/main/java/com/gdschongik/gdsc/global/security/CustomSuccessHandler.java @@ -45,7 +45,7 @@ public void onAuthenticationSuccess( // 랜딩 상태를 파라미터로 추가하여 리다이렉트 // String baseUrl = determineTargetUrl(request, response); - String baseUrl = PROD_CLIENT_URL + "/"; + String baseUrl = PROD_CLIENT_ONBOARDING_URL + "/"; String redirectUrl = String.format( SOCIAL_LOGIN_REDIRECT_URL, baseUrl, diff --git a/src/main/java/com/gdschongik/gdsc/global/util/email/VerificationLinkUtil.java b/src/main/java/com/gdschongik/gdsc/global/util/email/VerificationLinkUtil.java index ce90b32b2..39452a0d9 100644 --- a/src/main/java/com/gdschongik/gdsc/global/util/email/VerificationLinkUtil.java +++ b/src/main/java/com/gdschongik/gdsc/global/util/email/VerificationLinkUtil.java @@ -4,9 +4,9 @@ import static com.gdschongik.gdsc.global.common.constant.EmailConstant.VERIFY_EMAIL_REQUEST_PARAMETER_KEY; import static com.gdschongik.gdsc.global.common.constant.EnvironmentConstant.Constants.DEV_ENV; import static com.gdschongik.gdsc.global.common.constant.EnvironmentConstant.Constants.PROD_ENV; -import static com.gdschongik.gdsc.global.common.constant.UrlConstant.DEV_CLIENT_URL; +import static com.gdschongik.gdsc.global.common.constant.UrlConstant.DEV_CLIENT_ONBOARDING_URL; import static com.gdschongik.gdsc.global.common.constant.UrlConstant.LOCAL_VITE_CLIENT_SECURE_URL; -import static com.gdschongik.gdsc.global.common.constant.UrlConstant.PROD_CLIENT_URL; +import static com.gdschongik.gdsc.global.common.constant.UrlConstant.PROD_CLIENT_ONBOARDING_URL; import com.gdschongik.gdsc.global.util.EnvironmentUtil; import lombok.RequiredArgsConstructor; @@ -25,8 +25,8 @@ public String createLink(String verificationCode) { private String getClientUrl() { return switch (environmentUtil.getCurrentProfile()) { - case PROD_ENV -> PROD_CLIENT_URL; - case DEV_ENV -> DEV_CLIENT_URL; + case PROD_ENV -> PROD_CLIENT_ONBOARDING_URL; + case DEV_ENV -> DEV_CLIENT_ONBOARDING_URL; default -> LOCAL_VITE_CLIENT_SECURE_URL; }; } From 94e2cb7750ecbd32769e0aef166814e626fe67a8 Mon Sep 17 00:00:00 2001 From: Cho Sangwook <82208159+Sangwook02@users.noreply.github.com> Date: Thu, 29 Feb 2024 00:31:38 +0900 Subject: [PATCH 3/6] =?UTF-8?q?refactor:=20=EA=B2=80=EC=83=89=20=EC=A1=B0?= =?UTF-8?q?=EA=B1=B4=EC=97=90=EC=84=9C=20=ED=95=99=EA=B3=BC=EB=A5=BC=20?= =?UTF-8?q?=EB=AC=B8=EC=9E=90=EC=97=B4=EB=A1=9C=20=EB=B0=9B=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EC=88=98=EC=A0=95=20(#203)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor: 검색 조건에서 학과를 문자열로 받도록 수정 * refactor: 학과 코드 리스트 가져오는 로직을 Department로 이동 --- .../domain/member/dao/MemberCustomRepositoryImpl.java | 10 +++++----- .../gdsc/domain/member/domain/Department.java | 11 +++++++++++ .../domain/member/dto/request/MemberQueryRequest.java | 3 +-- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/gdschongik/gdsc/domain/member/dao/MemberCustomRepositoryImpl.java b/src/main/java/com/gdschongik/gdsc/domain/member/dao/MemberCustomRepositoryImpl.java index 3afb101bc..a0f55aa2a 100644 --- a/src/main/java/com/gdschongik/gdsc/domain/member/dao/MemberCustomRepositoryImpl.java +++ b/src/main/java/com/gdschongik/gdsc/domain/member/dao/MemberCustomRepositoryImpl.java @@ -177,12 +177,16 @@ private BooleanBuilder queryOption(MemberQueryRequest queryRequest) { .and(eqStudentId(queryRequest.studentId())) .and(eqName(queryRequest.name())) .and(eqPhone(queryRequest.phone())) - .and(eqDepartment(queryRequest.department())) + .and(inDepartmentList(Department.getDepartmentCodes(queryRequest.department()))) .and(eqEmail(queryRequest.email())) .and(eqDiscordUsername(queryRequest.discordUsername())) .and(eqNickname(queryRequest.nickname())); } + private BooleanExpression inDepartmentList(List departmentCodes) { + return departmentCodes != null ? member.department.in(departmentCodes) : null; + } + private BooleanExpression eqStudentId(String studentId) { return studentId != null ? member.studentId.containsIgnoreCase(studentId) : null; } @@ -195,10 +199,6 @@ private BooleanExpression eqPhone(String phone) { return phone != null ? member.phone.contains(phone.replaceAll("-", "")) : null; } - private BooleanExpression eqDepartment(Department department) { - return department != null ? member.department.eq(department) : null; - } - private BooleanExpression eqEmail(String email) { return email != null ? member.email.containsIgnoreCase(email) : null; } diff --git a/src/main/java/com/gdschongik/gdsc/domain/member/domain/Department.java b/src/main/java/com/gdschongik/gdsc/domain/member/domain/Department.java index aadaf5c74..184a77168 100644 --- a/src/main/java/com/gdschongik/gdsc/domain/member/domain/Department.java +++ b/src/main/java/com/gdschongik/gdsc/domain/member/domain/Department.java @@ -1,5 +1,8 @@ package com.gdschongik.gdsc.domain.member.domain; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; import lombok.AllArgsConstructor; import lombok.Getter; @@ -85,4 +88,12 @@ public enum Department { D077("영어교육과"); private String departmentName; + + public static List getDepartmentCodes(String keyword) { + return Optional.ofNullable(keyword) + .map(s -> Arrays.stream(Department.values()) + .filter(department -> department.getDepartmentName().contains(s)) + .toList()) + .orElse(null); + } } diff --git a/src/main/java/com/gdschongik/gdsc/domain/member/dto/request/MemberQueryRequest.java b/src/main/java/com/gdschongik/gdsc/domain/member/dto/request/MemberQueryRequest.java index ac3d23799..56ac95fa8 100644 --- a/src/main/java/com/gdschongik/gdsc/domain/member/dto/request/MemberQueryRequest.java +++ b/src/main/java/com/gdschongik/gdsc/domain/member/dto/request/MemberQueryRequest.java @@ -2,14 +2,13 @@ import static com.gdschongik.gdsc.global.common.constant.RegexConstant.*; -import com.gdschongik.gdsc.domain.member.domain.Department; import io.swagger.v3.oas.annotations.media.Schema; public record MemberQueryRequest( @Schema(description = "학번", pattern = STUDENT_ID) String studentId, @Schema(description = "이름") String name, @Schema(description = "전화번호", pattern = PHONE_WITHOUT_HYPHEN) String phone, - @Schema(description = "학과") Department department, + @Schema(description = "학과") String department, @Schema(description = "이메일") String email, @Schema(description = "디스코드 유저네임") String discordUsername, @Schema(description = "커뮤니티 닉네임", pattern = NICKNAME) String nickname) {} From 129eb4a414be6d6f7783ee87b3e02448a0455341 Mon Sep 17 00:00:00 2001 From: Cho Sangwook <82208159+Sangwook02@users.noreply.github.com> Date: Thu, 29 Feb 2024 00:33:54 +0900 Subject: [PATCH 4/6] =?UTF-8?q?refactor:=20=ED=95=99=EA=B3=BC=20=EC=A0=95?= =?UTF-8?q?=EB=B3=B4=EB=A5=BC=20=EC=BD=94=EB=93=9C=EC=99=80=20=EC=9D=B4?= =?UTF-8?q?=EB=A6=84=20=EB=AA=A8=EB=91=90=20=ED=8F=AC=ED=95=A8=ED=95=98?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95=20(#204)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor: 학과 정보를 코드와 이름 모두 포함하도록 수정 * refactor: dto 이름 수정 * refactor: api가 공유하던 dto 분리 * refactor: 어드민 회원 목록 api들의 response를 통일 * refactor: 레코드 이름 변경 * refactor: 가입 조건을 dto로 넣기 --- .../member/api/AdminMemberController.java | 20 ++++--- .../application/AdminMemberService.java | 21 ++++---- .../dto/response/AdminMemberResponse.java | 52 +++++++++++++++++++ .../dto/response/MemberFindAllResponse.java | 33 ------------ .../MemberPaymentFindAllResponse.java | 24 --------- .../MemberPendingFindAllResponse.java | 36 ------------- 6 files changed, 70 insertions(+), 116 deletions(-) create mode 100644 src/main/java/com/gdschongik/gdsc/domain/member/dto/response/AdminMemberResponse.java delete mode 100644 src/main/java/com/gdschongik/gdsc/domain/member/dto/response/MemberFindAllResponse.java delete mode 100644 src/main/java/com/gdschongik/gdsc/domain/member/dto/response/MemberPaymentFindAllResponse.java delete mode 100644 src/main/java/com/gdschongik/gdsc/domain/member/dto/response/MemberPendingFindAllResponse.java diff --git a/src/main/java/com/gdschongik/gdsc/domain/member/api/AdminMemberController.java b/src/main/java/com/gdschongik/gdsc/domain/member/api/AdminMemberController.java index ea9418eab..ba2c10d03 100644 --- a/src/main/java/com/gdschongik/gdsc/domain/member/api/AdminMemberController.java +++ b/src/main/java/com/gdschongik/gdsc/domain/member/api/AdminMemberController.java @@ -6,10 +6,8 @@ import com.gdschongik.gdsc.domain.member.dto.request.MemberPaymentRequest; import com.gdschongik.gdsc.domain.member.dto.request.MemberQueryRequest; import com.gdschongik.gdsc.domain.member.dto.request.MemberUpdateRequest; -import com.gdschongik.gdsc.domain.member.dto.response.MemberFindAllResponse; +import com.gdschongik.gdsc.domain.member.dto.response.AdminMemberResponse; import com.gdschongik.gdsc.domain.member.dto.response.MemberGrantResponse; -import com.gdschongik.gdsc.domain.member.dto.response.MemberPaymentFindAllResponse; -import com.gdschongik.gdsc.domain.member.dto.response.MemberPendingFindAllResponse; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; @@ -36,8 +34,8 @@ public class AdminMemberController { @Operation(summary = "전체 회원 목록 조회", description = "전체 회원 목록을 조회합니다.") @GetMapping - public ResponseEntity> getMembers(MemberQueryRequest queryRequest, Pageable pageable) { - Page response = adminMemberService.findAll(queryRequest, pageable); + public ResponseEntity> getMembers(MemberQueryRequest queryRequest, Pageable pageable) { + Page response = adminMemberService.findAll(queryRequest, pageable); return ResponseEntity.ok().body(response); } @@ -50,9 +48,9 @@ public ResponseEntity withdrawMember(@PathVariable Long memberId) { @Operation(summary = "대기중인 회원 목록 조회", description = "대기중인 회원 목록을 조회합니다.") @GetMapping("/pending") - public ResponseEntity> getPendingMembers( + public ResponseEntity> getPendingMembers( MemberQueryRequest queryRequest, Pageable pageable) { - Page response = adminMemberService.findAllPendingMembers(queryRequest, pageable); + Page response = adminMemberService.findAllPendingMembers(queryRequest, pageable); return ResponseEntity.ok().body(response); } @@ -73,19 +71,19 @@ public ResponseEntity grantMember(@Valid @RequestBody Membe @Operation(summary = "승인 가능 회원 전체 조회", description = "승인 가능한 회원 전체를 조회합니다.") @GetMapping("/grantable") - public ResponseEntity> getGrantableMembers( + public ResponseEntity> getGrantableMembers( MemberQueryRequest queryRequest, Pageable pageable) { - Page response = adminMemberService.getGrantableMembers(queryRequest, pageable); + Page response = adminMemberService.getGrantableMembers(queryRequest, pageable); return ResponseEntity.ok().body(response); } @Operation(summary = "회비 납부 상태에 따른 회원 전체 조회", description = "회비 납부 상태에 따라 회원 목록을 조회합니다.") @GetMapping("/payment") - public ResponseEntity> getMembersByPaymentStatus( + public ResponseEntity> getMembersByPaymentStatus( MemberQueryRequest queryRequest, @RequestParam(name = "status", required = false) RequirementStatus paymentStatus, Pageable pageable) { - Page response = + Page response = adminMemberService.getMembersByPaymentStatus(queryRequest, paymentStatus, pageable); return ResponseEntity.ok().body(response); } diff --git a/src/main/java/com/gdschongik/gdsc/domain/member/application/AdminMemberService.java b/src/main/java/com/gdschongik/gdsc/domain/member/application/AdminMemberService.java index c463d1742..7ea57a036 100644 --- a/src/main/java/com/gdschongik/gdsc/domain/member/application/AdminMemberService.java +++ b/src/main/java/com/gdschongik/gdsc/domain/member/application/AdminMemberService.java @@ -10,10 +10,8 @@ import com.gdschongik.gdsc.domain.member.dto.request.MemberPaymentRequest; import com.gdschongik.gdsc.domain.member.dto.request.MemberQueryRequest; import com.gdschongik.gdsc.domain.member.dto.request.MemberUpdateRequest; -import com.gdschongik.gdsc.domain.member.dto.response.MemberFindAllResponse; +import com.gdschongik.gdsc.domain.member.dto.response.AdminMemberResponse; import com.gdschongik.gdsc.domain.member.dto.response.MemberGrantResponse; -import com.gdschongik.gdsc.domain.member.dto.response.MemberPaymentFindAllResponse; -import com.gdschongik.gdsc.domain.member.dto.response.MemberPendingFindAllResponse; import com.gdschongik.gdsc.global.exception.CustomException; import com.gdschongik.gdsc.global.exception.ErrorCode; import java.util.List; @@ -31,9 +29,9 @@ public class AdminMemberService { private final MemberRepository memberRepository; - public Page findAll(MemberQueryRequest queryRequest, Pageable pageable) { + public Page findAll(MemberQueryRequest queryRequest, Pageable pageable) { Page members = memberRepository.findAll(queryRequest, pageable); - return members.map(MemberFindAllResponse::of); + return members.map(AdminMemberResponse::from); } @Transactional @@ -56,10 +54,9 @@ public void updateMember(Long memberId, MemberUpdateRequest request) { request.nickname()); } - public Page findAllPendingMembers( - MemberQueryRequest queryRequest, Pageable pageable) { + public Page findAllPendingMembers(MemberQueryRequest queryRequest, Pageable pageable) { Page members = memberRepository.findAllByRole(queryRequest, MemberRole.GUEST, pageable); - return members.map(MemberPendingFindAllResponse::of); + return members.map(AdminMemberResponse::from); } @Transactional @@ -70,15 +67,15 @@ public MemberGrantResponse grantMember(MemberGrantRequest request) { return MemberGrantResponse.from(classifiedMember); } - public Page getGrantableMembers(MemberQueryRequest queryRequest, Pageable pageable) { + public Page getGrantableMembers(MemberQueryRequest queryRequest, Pageable pageable) { Page members = memberRepository.findAllGrantable(queryRequest, pageable); - return members.map(MemberFindAllResponse::of); + return members.map(AdminMemberResponse::from); } - public Page getMembersByPaymentStatus( + public Page getMembersByPaymentStatus( MemberQueryRequest queryRequest, RequirementStatus paymentStatus, Pageable pageable) { Page members = memberRepository.findAllByPaymentStatus(queryRequest, paymentStatus, pageable); - return members.map(MemberPaymentFindAllResponse::from); + return members.map(AdminMemberResponse::from); } @Transactional diff --git a/src/main/java/com/gdschongik/gdsc/domain/member/dto/response/AdminMemberResponse.java b/src/main/java/com/gdschongik/gdsc/domain/member/dto/response/AdminMemberResponse.java new file mode 100644 index 000000000..312a6f216 --- /dev/null +++ b/src/main/java/com/gdschongik/gdsc/domain/member/dto/response/AdminMemberResponse.java @@ -0,0 +1,52 @@ +package com.gdschongik.gdsc.domain.member.dto.response; + +import com.gdschongik.gdsc.domain.member.domain.Department; +import com.gdschongik.gdsc.domain.member.domain.Member; +import com.gdschongik.gdsc.domain.member.domain.Requirement; +import java.util.Optional; + +public record AdminMemberResponse( + Long memberId, + String studentId, + String name, + String phone, + DepartmentDto department, + String email, + String discordUsername, + String nickname, + RequirementDto requirement) { + + public static AdminMemberResponse from(Member member) { + return new AdminMemberResponse( + member.getId(), + member.getStudentId(), + member.getName(), + Optional.ofNullable(member.getPhone()) + .map(phone -> String.format( + "%s-%s-%s", phone.substring(0, 3), phone.substring(3, 7), phone.substring(7))) + .orElse(null), + DepartmentDto.from(member.getDepartment()), + member.getEmail(), + member.getDiscordUsername(), + member.getNickname(), + RequirementDto.from(member.getRequirement())); + } + + record DepartmentDto(Department code, String name) { + public static DepartmentDto from(Department department) { + return Optional.ofNullable(department) + .map(code -> new DepartmentDto(code, code.getDepartmentName())) + .orElse(new DepartmentDto(null, null)); + } + } + + record RequirementDto(String univStatus, String discordStatus, String paymentStatus, String bevyStatus) { + public static RequirementDto from(Requirement requirement) { + return new RequirementDto( + requirement.getUnivStatus().name(), + requirement.getDiscordStatus().name(), + requirement.getPaymentStatus().name(), + requirement.getBevyStatus().name()); + } + } +} diff --git a/src/main/java/com/gdschongik/gdsc/domain/member/dto/response/MemberFindAllResponse.java b/src/main/java/com/gdschongik/gdsc/domain/member/dto/response/MemberFindAllResponse.java deleted file mode 100644 index a0bf28b93..000000000 --- a/src/main/java/com/gdschongik/gdsc/domain/member/dto/response/MemberFindAllResponse.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.gdschongik.gdsc.domain.member.dto.response; - -import com.gdschongik.gdsc.domain.member.domain.Department; -import com.gdschongik.gdsc.domain.member.domain.Member; -import java.util.Optional; - -public record MemberFindAllResponse( - Long memberId, - String studentId, - String name, - String phone, - String department, - String email, - String discordUsername, - String nickname) { - - public static MemberFindAllResponse of(Member member) { - return new MemberFindAllResponse( - member.getId(), - member.getStudentId(), - member.getName(), - Optional.ofNullable(member.getPhone()) - .map(phone -> String.format( - "%s-%s-%s", phone.substring(0, 3), phone.substring(3, 7), phone.substring(7))) - .orElse(null), - Optional.ofNullable(member.getDepartment()) - .map(Department::getDepartmentName) - .orElse(null), - member.getEmail(), - member.getDiscordUsername(), - member.getNickname()); - } -} diff --git a/src/main/java/com/gdschongik/gdsc/domain/member/dto/response/MemberPaymentFindAllResponse.java b/src/main/java/com/gdschongik/gdsc/domain/member/dto/response/MemberPaymentFindAllResponse.java deleted file mode 100644 index 97d3b9482..000000000 --- a/src/main/java/com/gdschongik/gdsc/domain/member/dto/response/MemberPaymentFindAllResponse.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.gdschongik.gdsc.domain.member.dto.response; - -import com.gdschongik.gdsc.domain.member.domain.Member; -import com.gdschongik.gdsc.domain.member.domain.RequirementStatus; - -public record MemberPaymentFindAllResponse( - Long memberId, - String studentId, - String name, - String phone, - String discordUsername, - String nickname, - RequirementStatus paymentStatus) { - public static MemberPaymentFindAllResponse from(Member member) { - return new MemberPaymentFindAllResponse( - member.getId(), - member.getStudentId(), - member.getName(), - member.getPhone(), - member.getDiscordUsername(), - member.getNickname(), - member.getRequirement().getPaymentStatus()); - } -} diff --git a/src/main/java/com/gdschongik/gdsc/domain/member/dto/response/MemberPendingFindAllResponse.java b/src/main/java/com/gdschongik/gdsc/domain/member/dto/response/MemberPendingFindAllResponse.java deleted file mode 100644 index 4f216d151..000000000 --- a/src/main/java/com/gdschongik/gdsc/domain/member/dto/response/MemberPendingFindAllResponse.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.gdschongik.gdsc.domain.member.dto.response; - -import com.gdschongik.gdsc.domain.member.domain.Department; -import com.gdschongik.gdsc.domain.member.domain.Member; -import com.gdschongik.gdsc.domain.member.domain.Requirement; -import java.util.Optional; - -public record MemberPendingFindAllResponse( - Long memberId, - String studentId, - String name, - String phone, - String department, - String email, - String discordUsername, - String nickname, - Requirement requirement) { - - public static MemberPendingFindAllResponse of(Member member) { - return new MemberPendingFindAllResponse( - member.getId(), - member.getStudentId(), - member.getName(), - Optional.ofNullable(member.getPhone()) - .map(phone -> String.format( - "%s-%s-%s", phone.substring(0, 3), phone.substring(3, 7), phone.substring(7))) - .orElse(null), - Optional.ofNullable(member.getDepartment()) - .map(Department::getDepartmentName) - .orElse(null), - member.getEmail(), - member.getDiscordUsername(), - member.getNickname(), - member.getRequirement()); - } -} From 00033b3d99863ccd223b19ee598aa416a3f7a072 Mon Sep 17 00:00:00 2001 From: Jaehyun Ahn <91878695+uwoobeat@users.noreply.github.com> Date: Thu, 29 Feb 2024 21:33:29 +0900 Subject: [PATCH 5/6] =?UTF-8?q?feat:=20=EB=A6=AC=EB=8B=A4=EC=9D=B4?= =?UTF-8?q?=EB=A0=89=ED=8A=B8=20=EC=9C=84=EC=B9=98=EB=A5=BC=20=EB=A0=88?= =?UTF-8?q?=ED=8D=BC=EB=9F=AC=EA=B0=80=20=EC=95=84=EB=8B=8C=20=EC=BF=A0?= =?UTF-8?q?=ED=82=A4=EC=97=90=EC=84=9C=20=EB=A1=9C=EB=93=9C=ED=95=98?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EB=B3=80=EA=B2=BD=20(#210)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 쿠키 유틸리티 로직 추가 * feat: 시큐리티 상수 추가 * feat: 커스텀 요청 저장소 추가 * feat: 쿠키에 저장된 값을 꺼내서 리다이렉트하도록 수정 * feat: 쿠키 유틸리티 로직 원복 * fix: 마지막 로그인 시간 업데이트 * feat: 쿠키 저장소 제거 * feat: 파라미터를 OAuth2 객체로 매핑하는 리졸버 구현 * feat: 리졸버의 리다이렉트 URI 사용하도록 변경 * feat: 커스텀 파라미터 리졸버 삭제 * feat: 인증유저 클래스에서 리다이렉트 URI 프로퍼티 제거 * feat: 시큐리티 상수 업데이트 * feat: URL 상수 업데이트 * feat: 쿠키에서 리다이렉트할 URL을 가져오도록 구현 * feat: 서블릿 쿠키에 대한 유틸리티 메서드 추가 * refactor: 문자열 포맷 대신 URI 빌더를 사용하도록 개선 * feat: 쿠키 삭제방식 변경 * chore: 정적 임포트 추가 --- .../common/constant/SecurityConstant.java | 3 ++ .../global/common/constant/UrlConstant.java | 9 +++- .../gdsc/global/exception/ErrorCode.java | 2 + .../global/security/CustomSuccessHandler.java | 50 +++++++++++++------ .../global/security/CustomUserService.java | 5 ++ .../gdsc/global/util/CookieUtil.java | 22 ++++++-- 6 files changed, 72 insertions(+), 19 deletions(-) diff --git a/src/main/java/com/gdschongik/gdsc/global/common/constant/SecurityConstant.java b/src/main/java/com/gdschongik/gdsc/global/common/constant/SecurityConstant.java index 77feb0f8a..622a2a359 100644 --- a/src/main/java/com/gdschongik/gdsc/global/common/constant/SecurityConstant.java +++ b/src/main/java/com/gdschongik/gdsc/global/common/constant/SecurityConstant.java @@ -3,10 +3,13 @@ public class SecurityConstant { public static final String LANDING_STATUS_PARAM = "landing-status"; + public static final String ACCESS_TOKEN_PARAM = "access"; + public static final String REFRESH_TOKEN_PARAM = "refresh"; public static final String TOKEN_ROLE_NAME = "role"; public static final String GITHUB_NAME_ATTR_KEY = "id"; public static final String ACCESS_TOKEN_HEADER_PREFIX = "Bearer "; public static final String ACCESS_TOKEN_HEADER_NAME = "Authorization"; + public static final String OAUTH_BASE_URI_COOKIE_NAME = "oauth-base-uri"; private SecurityConstant() {} } diff --git a/src/main/java/com/gdschongik/gdsc/global/common/constant/UrlConstant.java b/src/main/java/com/gdschongik/gdsc/global/common/constant/UrlConstant.java index a54bd8eda..07d575690 100644 --- a/src/main/java/com/gdschongik/gdsc/global/common/constant/UrlConstant.java +++ b/src/main/java/com/gdschongik/gdsc/global/common/constant/UrlConstant.java @@ -2,10 +2,13 @@ import static com.gdschongik.gdsc.global.common.constant.SecurityConstant.*; +import java.util.List; + public class UrlConstant { private UrlConstant() {} + // 클라이언트 URL public static final String PROD_CLIENT_ONBOARDING_URL = "https://onboarding.gdschongik.com"; public static final String PROD_CLIENT_ADMIN_URL = "https://admin.gdschongik.com"; public static final String DEV_CLIENT_ONBOARDING_URL = "https://dev-onboarding.gdschongik.com"; @@ -14,10 +17,14 @@ private UrlConstant() {} public static final String LOCAL_REACT_CLIENT_SECURE_URL = "https://localhost:3000"; public static final String LOCAL_VITE_CLIENT_URL = "http://localhost:5173"; public static final String LOCAL_VITE_CLIENT_SECURE_URL = "https://localhost:5173"; + public static final List LOCAL_CLIENT_URLS = List.of( + LOCAL_REACT_CLIENT_URL, LOCAL_REACT_CLIENT_SECURE_URL, LOCAL_VITE_CLIENT_URL, LOCAL_VITE_CLIENT_SECURE_URL); + // 서버 URL public static final String PROD_SERVER_URL = "https://api.gdschongik.com"; public static final String DEV_SERVER_URL = "https://dev-api.gdschongik.com"; public static final String LOCAL_SERVER_URL = "http://localhost:8080"; - public static final String SOCIAL_LOGIN_REDIRECT_URL = "%ssocial-login/redirect?%s=%s&%s=%s&%s=%s"; + // 기타 + public static final String ROOT_DOMAIN = "gdschongik.com"; } diff --git a/src/main/java/com/gdschongik/gdsc/global/exception/ErrorCode.java b/src/main/java/com/gdschongik/gdsc/global/exception/ErrorCode.java index c5a3b3663..d096fcfb3 100644 --- a/src/main/java/com/gdschongik/gdsc/global/exception/ErrorCode.java +++ b/src/main/java/com/gdschongik/gdsc/global/exception/ErrorCode.java @@ -17,6 +17,8 @@ public enum ErrorCode { EXPIRED_JWT_TOKEN(HttpStatus.UNAUTHORIZED, "만료된 JWT 토큰입니다."), AUTH_NOT_EXIST(HttpStatus.INTERNAL_SERVER_ERROR, "시큐리티 인증 정보가 존재하지 않습니다."), AUTH_NOT_PARSABLE(HttpStatus.INTERNAL_SERVER_ERROR, "시큐리티 인증 정보 파싱에 실패했습니다."), + BASE_URI_COOKIE_NOT_FOUND(HttpStatus.NOT_FOUND, "Base URI 쿠키가 존재하지 않습니다."), + NOT_ALLOWED_BASE_URI(HttpStatus.FORBIDDEN, "허용되지 않은 Base URI입니다."), // Parameter INVALID_QUERY_PARAMETER(HttpStatus.BAD_REQUEST, "잘못된 쿼리 파라미터입니다."), diff --git a/src/main/java/com/gdschongik/gdsc/global/security/CustomSuccessHandler.java b/src/main/java/com/gdschongik/gdsc/global/security/CustomSuccessHandler.java index a2275c441..967a818f3 100644 --- a/src/main/java/com/gdschongik/gdsc/global/security/CustomSuccessHandler.java +++ b/src/main/java/com/gdschongik/gdsc/global/security/CustomSuccessHandler.java @@ -2,18 +2,22 @@ import static com.gdschongik.gdsc.global.common.constant.SecurityConstant.*; import static com.gdschongik.gdsc.global.common.constant.UrlConstant.*; +import static com.gdschongik.gdsc.global.exception.ErrorCode.*; import com.gdschongik.gdsc.domain.auth.application.JwtService; import com.gdschongik.gdsc.domain.auth.dto.AccessTokenDto; import com.gdschongik.gdsc.domain.auth.dto.RefreshTokenDto; +import com.gdschongik.gdsc.global.exception.CustomException; import com.gdschongik.gdsc.global.util.CookieUtil; import jakarta.servlet.ServletException; +import jakarta.servlet.http.Cookie; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import lombok.extern.slf4j.Slf4j; import org.springframework.security.core.Authentication; import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler; +import org.springframework.web.util.UriComponentsBuilder; @Slf4j public class CustomSuccessHandler extends SimpleUrlAuthenticationSuccessHandler { @@ -24,13 +28,13 @@ public class CustomSuccessHandler extends SimpleUrlAuthenticationSuccessHandler public CustomSuccessHandler(JwtService jwtService, CookieUtil cookieUtil) { this.jwtService = jwtService; this.cookieUtil = cookieUtil; - this.setUseReferer(true); } @Override public void onAuthenticationSuccess( HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws ServletException, IOException { + String baseUri = determineTargetUrl(request, response); CustomOAuth2User oAuth2User = (CustomOAuth2User) authentication.getPrincipal(); @@ -43,19 +47,35 @@ public void onAuthenticationSuccess( // 임시로 헤더에 엑세스 토큰 추가 response.addHeader(ACCESS_TOKEN_HEADER_NAME, ACCESS_TOKEN_HEADER_PREFIX + accessTokenDto.tokenValue()); - // 랜딩 상태를 파라미터로 추가하여 리다이렉트 - // String baseUrl = determineTargetUrl(request, response); - String baseUrl = PROD_CLIENT_ONBOARDING_URL + "/"; - String redirectUrl = String.format( - SOCIAL_LOGIN_REDIRECT_URL, - baseUrl, - LANDING_STATUS_PARAM, - oAuth2User.getLandingStatus().name(), - "access", - accessTokenDto.tokenValue(), - "refresh", - refreshTokenDto.tokenValue()); - - getRedirectStrategy().sendRedirect(request, response, redirectUrl); + String redirectUri = UriComponentsBuilder.fromHttpUrl(baseUri) + .queryParam(LANDING_STATUS_PARAM, oAuth2User.getLandingStatus().name()) + .queryParam(ACCESS_TOKEN_PARAM, accessTokenDto.tokenValue()) + .queryParam(REFRESH_TOKEN_PARAM, refreshTokenDto.tokenValue()) + .toUriString(); + + getRedirectStrategy().sendRedirect(request, response, redirectUri); + } + + @Override + protected String determineTargetUrl(HttpServletRequest request, HttpServletResponse response) { + Cookie baseUriCookie = cookieUtil + .findCookie(request, OAUTH_BASE_URI_COOKIE_NAME) + .orElseThrow(() -> new CustomException(BASE_URI_COOKIE_NOT_FOUND)); + + String baseUri = baseUriCookie.getValue(); + validateBaseUri(baseUri); + + cookieUtil.deleteCookie(response, baseUriCookie); + + return baseUri; + } + + private void validateBaseUri(String baseUri) { + if (baseUri.endsWith(ROOT_DOMAIN) || LOCAL_CLIENT_URLS.contains(baseUri)) { + return; + } + + log.error("허용되지 않은 BASE URI로의 리다이렉트 요청 발생: {}", baseUri); + throw new CustomException(NOT_ALLOWED_BASE_URI); } } diff --git a/src/main/java/com/gdschongik/gdsc/global/security/CustomUserService.java b/src/main/java/com/gdschongik/gdsc/global/security/CustomUserService.java index 4ab53c807..076c317b7 100644 --- a/src/main/java/com/gdschongik/gdsc/global/security/CustomUserService.java +++ b/src/main/java/com/gdschongik/gdsc/global/security/CustomUserService.java @@ -1,5 +1,7 @@ package com.gdschongik.gdsc.global.security; +import static com.gdschongik.gdsc.global.common.constant.SecurityConstant.*; + import com.gdschongik.gdsc.domain.member.dao.MemberRepository; import com.gdschongik.gdsc.domain.member.domain.Member; import lombok.RequiredArgsConstructor; @@ -18,8 +20,11 @@ public class CustomUserService extends DefaultOAuth2UserService { @Override public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException { OAuth2User oAuth2User = super.loadUser(userRequest); + Member member = fetchOrCreate(oAuth2User); member.updateLastLoginAt(); + memberRepository.save(member); + return new CustomOAuth2User(oAuth2User, member); } diff --git a/src/main/java/com/gdschongik/gdsc/global/util/CookieUtil.java b/src/main/java/com/gdschongik/gdsc/global/util/CookieUtil.java index 21556abca..b8722d1b9 100644 --- a/src/main/java/com/gdschongik/gdsc/global/util/CookieUtil.java +++ b/src/main/java/com/gdschongik/gdsc/global/util/CookieUtil.java @@ -1,7 +1,10 @@ package com.gdschongik.gdsc.global.util; import com.gdschongik.gdsc.global.common.constant.JwtConstant; +import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; +import java.util.Arrays; +import java.util.Optional; import lombok.RequiredArgsConstructor; import org.springframework.boot.web.server.Cookie; import org.springframework.http.HttpHeaders; @@ -19,16 +22,16 @@ public void addTokenCookies(HttpServletResponse response, String accessToken, St String sameSite = determineSameSitePolicy(); ResponseCookie accessTokenCookie = - generateCookie(JwtConstant.ACCESS_TOKEN.getCookieName(), accessToken, sameSite); + generateTokenCookie(JwtConstant.ACCESS_TOKEN.getCookieName(), accessToken, sameSite); ResponseCookie refreshTokenCookie = - generateCookie(JwtConstant.REFRESH_TOKEN.getCookieName(), refreshToken, sameSite); + generateTokenCookie(JwtConstant.REFRESH_TOKEN.getCookieName(), refreshToken, sameSite); response.addHeader(HttpHeaders.SET_COOKIE, accessTokenCookie.toString()); response.addHeader(HttpHeaders.SET_COOKIE, refreshTokenCookie.toString()); } - private ResponseCookie generateCookie(String cookieName, String tokenValue, String sameSite) { + private ResponseCookie generateTokenCookie(String cookieName, String tokenValue, String sameSite) { return ResponseCookie.from(cookieName, tokenValue) .path("/") .secure(true) @@ -43,4 +46,17 @@ private String determineSameSitePolicy() { } return Cookie.SameSite.NONE.attributeValue(); } + + public Optional findCookie(HttpServletRequest request, String cookieName) { + return Arrays.stream(request.getCookies()) + .filter(cookie -> cookie.getName().equals(cookieName)) + .findFirst(); + } + + public void deleteCookie(HttpServletResponse response, jakarta.servlet.http.Cookie cookie) { + cookie.setPath("/"); + cookie.setValue(""); + cookie.setMaxAge(0); + response.addCookie(cookie); + } } From dda84331f16bc7eee0211ad4a82fc6193514e3b8 Mon Sep 17 00:00:00 2001 From: Jaehyun Ahn <91878695+uwoobeat@users.noreply.github.com> Date: Fri, 1 Mar 2024 21:31:29 +0900 Subject: [PATCH 6/6] =?UTF-8?q?fix:=20=EB=A6=AC=EB=8B=A4=EC=9D=B4=EB=A0=89?= =?UTF-8?q?=ED=8A=B8=20URL=20=EC=84=B8=EA=B7=B8=EB=A8=BC=ED=8A=B8=EA=B0=80?= =?UTF-8?q?=20=EB=88=84=EB=9D=BD=EB=90=98=EC=96=B4=20=EC=9E=88=EB=8A=94=20?= =?UTF-8?q?=EB=AC=B8=EC=A0=9C=20=EC=88=98=EC=A0=95=20(#213)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix: 리다이렉트 URL 세그먼트 추가 --- .../gdschongik/gdsc/global/common/constant/SecurityConstant.java | 1 + .../gdschongik/gdsc/global/security/CustomSuccessHandler.java | 1 + 2 files changed, 2 insertions(+) diff --git a/src/main/java/com/gdschongik/gdsc/global/common/constant/SecurityConstant.java b/src/main/java/com/gdschongik/gdsc/global/common/constant/SecurityConstant.java index 622a2a359..ebb0770c3 100644 --- a/src/main/java/com/gdschongik/gdsc/global/common/constant/SecurityConstant.java +++ b/src/main/java/com/gdschongik/gdsc/global/common/constant/SecurityConstant.java @@ -10,6 +10,7 @@ public class SecurityConstant { public static final String ACCESS_TOKEN_HEADER_PREFIX = "Bearer "; public static final String ACCESS_TOKEN_HEADER_NAME = "Authorization"; public static final String OAUTH_BASE_URI_COOKIE_NAME = "oauth-base-uri"; + public static final String OAUTH_REDIRECT_PATH_SEGMENT = "/social-login/redirect"; private SecurityConstant() {} } diff --git a/src/main/java/com/gdschongik/gdsc/global/security/CustomSuccessHandler.java b/src/main/java/com/gdschongik/gdsc/global/security/CustomSuccessHandler.java index 967a818f3..e60e28240 100644 --- a/src/main/java/com/gdschongik/gdsc/global/security/CustomSuccessHandler.java +++ b/src/main/java/com/gdschongik/gdsc/global/security/CustomSuccessHandler.java @@ -48,6 +48,7 @@ public void onAuthenticationSuccess( response.addHeader(ACCESS_TOKEN_HEADER_NAME, ACCESS_TOKEN_HEADER_PREFIX + accessTokenDto.tokenValue()); String redirectUri = UriComponentsBuilder.fromHttpUrl(baseUri) + .path(OAUTH_REDIRECT_PATH_SEGMENT) .queryParam(LANDING_STATUS_PARAM, oAuth2User.getLandingStatus().name()) .queryParam(ACCESS_TOKEN_PARAM, accessTokenDto.tokenValue()) .queryParam(REFRESH_TOKEN_PARAM, refreshTokenDto.tokenValue())