diff --git a/src/main/java/com/dreamypatisiel/devdevdev/global/security/jwt/model/JwtCookieConstant.java b/src/main/java/com/dreamypatisiel/devdevdev/global/security/jwt/model/JwtCookieConstant.java index 1c14122f..cea3f392 100644 --- a/src/main/java/com/dreamypatisiel/devdevdev/global/security/jwt/model/JwtCookieConstant.java +++ b/src/main/java/com/dreamypatisiel/devdevdev/global/security/jwt/model/JwtCookieConstant.java @@ -7,4 +7,5 @@ public class JwtCookieConstant { public static final String DEVDEVDEV_MEMBER_NICKNAME = "DEVDEVDEV_MEMBER_NICKNAME"; public static final String DEVDEVDEV_MEMBER_EMAIL = "DEVDEVDEV_MEMBER_EMAIL"; public static final String DEVDEVDEV_MEMBER_IS_ADMIN = "DEVDEVDEV_MEMBER_IS_ADMIN"; + public static final String DEVDEVDEV_MEMBER_IS_NEW = "DEVDEVDEV_MEMBER_IS_NEW"; } diff --git a/src/main/java/com/dreamypatisiel/devdevdev/global/security/oauth2/handler/OAuth2SuccessHandler.java b/src/main/java/com/dreamypatisiel/devdevdev/global/security/oauth2/handler/OAuth2SuccessHandler.java index a1c634e9..57401d4a 100644 --- a/src/main/java/com/dreamypatisiel/devdevdev/global/security/oauth2/handler/OAuth2SuccessHandler.java +++ b/src/main/java/com/dreamypatisiel/devdevdev/global/security/oauth2/handler/OAuth2SuccessHandler.java @@ -3,15 +3,19 @@ import com.dreamypatisiel.devdevdev.domain.entity.Member; import com.dreamypatisiel.devdevdev.domain.entity.enums.SocialType; import com.dreamypatisiel.devdevdev.global.common.MemberProvider; +import com.dreamypatisiel.devdevdev.global.security.jwt.model.JwtCookieConstant; import com.dreamypatisiel.devdevdev.global.security.jwt.model.Token; import com.dreamypatisiel.devdevdev.global.security.jwt.service.JwtMemberService; import com.dreamypatisiel.devdevdev.global.security.jwt.service.TokenService; import com.dreamypatisiel.devdevdev.global.security.oauth2.model.OAuth2UserProvider; +import com.dreamypatisiel.devdevdev.global.security.oauth2.model.UserPrincipal; import com.dreamypatisiel.devdevdev.global.utils.CookieUtils; import com.dreamypatisiel.devdevdev.global.utils.UriUtils; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; +import java.util.Collection; + import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; @@ -53,8 +57,9 @@ public void onAuthenticationSuccess(HttpServletRequest request, HttpServletRespo CookieUtils.configJwtCookie(response, token); // 유저 정보 쿠키에 저장 + UserPrincipal userPrincipal = (UserPrincipal) authentication.getPrincipal(); Member member = memberProvider.getMemberByAuthentication(authentication); - CookieUtils.configMemberCookie(response, member); + CookieUtils.configMemberCookie(response, member, userPrincipal.isNewMember()); // 리다이렉트 설정 String redirectUri = UriUtils.createUriByDomainAndEndpoint(domain, endpoint); diff --git a/src/main/java/com/dreamypatisiel/devdevdev/global/security/oauth2/model/UserPrincipal.java b/src/main/java/com/dreamypatisiel/devdevdev/global/security/oauth2/model/UserPrincipal.java index be13efd5..2327d8be 100644 --- a/src/main/java/com/dreamypatisiel/devdevdev/global/security/oauth2/model/UserPrincipal.java +++ b/src/main/java/com/dreamypatisiel/devdevdev/global/security/oauth2/model/UserPrincipal.java @@ -34,6 +34,8 @@ public class UserPrincipal implements OAuth2User, UserDetails { private final Collection authorities; @Setter(value = AccessLevel.PRIVATE) private Map attributes = new HashMap<>(); + @Getter + private boolean isNewMember; public static UserPrincipal createByMember(Member member) { List simpleGrantedAuthorities = Collections.singletonList( @@ -51,9 +53,10 @@ public static UserPrincipal createByMember(Member member) { ); } - public static UserPrincipal createByMemberAndAttributes(Member member, Map attributes) { + public static UserPrincipal createByMemberAndAttributes(Member member, Map attributes, boolean isNewMember) { UserPrincipal userPrincipal = UserPrincipal.createByMember(member); userPrincipal.setAttributes(attributes); + userPrincipal.isNewMember = isNewMember; return userPrincipal; } diff --git a/src/main/java/com/dreamypatisiel/devdevdev/global/security/oauth2/service/OAuth2MemberService.java b/src/main/java/com/dreamypatisiel/devdevdev/global/security/oauth2/service/OAuth2MemberService.java index 2e2472e5..795002cc 100644 --- a/src/main/java/com/dreamypatisiel/devdevdev/global/security/oauth2/service/OAuth2MemberService.java +++ b/src/main/java/com/dreamypatisiel/devdevdev/global/security/oauth2/service/OAuth2MemberService.java @@ -27,7 +27,7 @@ public class OAuth2MemberService { public UserPrincipal register(OAuth2UserProvider oAuth2UserProvider, OAuth2User oAuth2User) { Optional optionalMember = findMemberByOAuth2UserProvider(oAuth2UserProvider); if (optionalMember.isPresent()) { - return UserPrincipal.createByMemberAndAttributes(optionalMember.get(), oAuth2User.getAttributes()); + return UserPrincipal.createByMemberAndAttributes(optionalMember.get(), oAuth2User.getAttributes(), false); } // 데이터베이스 회원이 없으면 회원가입 시킨다. @@ -40,7 +40,7 @@ public UserPrincipal register(OAuth2UserProvider oAuth2UserProvider, OAuth2User Member newMember = memberRepository.save(Member.createMemberBy(socialMemberDto)); - return UserPrincipal.createByMemberAndAttributes(newMember, oAuth2User.getAttributes()); + return UserPrincipal.createByMemberAndAttributes(newMember, oAuth2User.getAttributes(), true); } private Optional findMemberByOAuth2UserProvider(OAuth2UserProvider oAuth2UserProvider) { diff --git a/src/main/java/com/dreamypatisiel/devdevdev/global/utils/CookieUtils.java b/src/main/java/com/dreamypatisiel/devdevdev/global/utils/CookieUtils.java index e12b39dd..fcdabd09 100644 --- a/src/main/java/com/dreamypatisiel/devdevdev/global/utils/CookieUtils.java +++ b/src/main/java/com/dreamypatisiel/devdevdev/global/utils/CookieUtils.java @@ -99,7 +99,7 @@ public static void configJwtCookie(HttpServletResponse response, Token token) { ACTIVE, DEFAULT_MAX_AGE, false, true); } - public static void configMemberCookie(HttpServletResponse response, Member member) { + public static void configMemberCookie(HttpServletResponse response, Member member, boolean isNewMember) { // 닉네임 UTF-8 인코딩 필요 String nickname = URLEncoder.encode(member.getNicknameAsString(), StandardCharsets.UTF_8); @@ -109,6 +109,8 @@ public static void configMemberCookie(HttpServletResponse response, Member membe member.getEmailAsString(), DEFAULT_MAX_AGE, false, true); addCookieToResponse(response, JwtCookieConstant.DEVDEVDEV_MEMBER_IS_ADMIN, String.valueOf(member.isAdmin()), DEFAULT_MAX_AGE, false, true); + addCookieToResponse(response, JwtCookieConstant.DEVDEVDEV_MEMBER_IS_NEW, + String.valueOf(isNewMember), DEFAULT_MAX_AGE, false, true); } private static void validationCookieEmpty(Cookie[] cookies) { diff --git a/src/test/java/com/dreamypatisiel/devdevdev/global/security/oauth2/handler/OAuth2SuccessHandlerTest.java b/src/test/java/com/dreamypatisiel/devdevdev/global/security/oauth2/handler/OAuth2SuccessHandlerTest.java index 17cfbae9..f952fd57 100644 --- a/src/test/java/com/dreamypatisiel/devdevdev/global/security/oauth2/handler/OAuth2SuccessHandlerTest.java +++ b/src/test/java/com/dreamypatisiel/devdevdev/global/security/oauth2/handler/OAuth2SuccessHandlerTest.java @@ -56,7 +56,7 @@ void simulateOAuth2Login() { Map kakaoAttributes = new HashMap<>(); kakaoAttributes.put(KakaoMember.EMAIL, email); attributes.put(KakaoMember.KAKAO_ACCOUNT, kakaoAttributes); - UserPrincipal userPrincipal = UserPrincipal.createByMemberAndAttributes(member, attributes); + UserPrincipal userPrincipal = UserPrincipal.createByMemberAndAttributes(member, attributes, false); // OAuth2AuthenticationToken 생성 SecurityContext context = SecurityContextHolder.getContext(); @@ -82,6 +82,7 @@ public void onAuthenticationSuccessException() { @DisplayName("OAuth2.0 로그인 성공 시" + " 토큰을 생성하고 토큰을 쿠키에 저장하고" + " 로그인된 회원의 이메일과 닉네임을 쿠키에 저장하고" + + " 로그인된 회원의 신규회원 여부를 쿠키에 저장하고" + " 리다이렉트를 설정하고" + " 회원에 리프레시 토큰을 저장한다.") void onAuthenticationSuccess() throws IOException { @@ -105,6 +106,7 @@ void onAuthenticationSuccess() throws IOException { Cookie nicknameCookie = response.getCookie(JwtCookieConstant.DEVDEVDEV_MEMBER_NICKNAME); Cookie emailCookie = response.getCookie(JwtCookieConstant.DEVDEVDEV_MEMBER_EMAIL); Cookie isAdmin = response.getCookie(JwtCookieConstant.DEVDEVDEV_MEMBER_IS_ADMIN); + Cookie isNewMember = response.getCookie(JwtCookieConstant.DEVDEVDEV_MEMBER_IS_NEW); assertAll( () -> assertThat(accessCookie).isNotNull(), @@ -112,7 +114,8 @@ void onAuthenticationSuccess() throws IOException { () -> assertThat(loginStatusCookie).isNotNull(), () -> assertThat(nicknameCookie).isNotNull(), () -> assertThat(emailCookie).isNotNull(), - () -> assertThat(isAdmin).isNotNull() + () -> assertThat(isAdmin).isNotNull(), + () -> assertThat(isNewMember).isNotNull() ); assertAll( () -> assertThat(accessCookie.isHttpOnly()).isFalse(), diff --git a/src/test/java/com/dreamypatisiel/devdevdev/global/security/oauth2/model/UserPrincipalTest.java b/src/test/java/com/dreamypatisiel/devdevdev/global/security/oauth2/model/UserPrincipalTest.java index efb9ec21..b997901a 100644 --- a/src/test/java/com/dreamypatisiel/devdevdev/global/security/oauth2/model/UserPrincipalTest.java +++ b/src/test/java/com/dreamypatisiel/devdevdev/global/security/oauth2/model/UserPrincipalTest.java @@ -52,7 +52,7 @@ void createByMemberAndAttributes() { Map attributes = new HashMap<>(); // when - UserPrincipal userPrincipal = UserPrincipal.createByMemberAndAttributes(member, attributes); + UserPrincipal userPrincipal = UserPrincipal.createByMemberAndAttributes(member, attributes, false); // then assertAll( diff --git a/src/test/java/com/dreamypatisiel/devdevdev/global/security/oauth2/service/AppOAuth2MemberServiceTest.java b/src/test/java/com/dreamypatisiel/devdevdev/global/security/oauth2/service/AppOAuth2MemberServiceTest.java index f7410f31..2942d324 100644 --- a/src/test/java/com/dreamypatisiel/devdevdev/global/security/oauth2/service/AppOAuth2MemberServiceTest.java +++ b/src/test/java/com/dreamypatisiel/devdevdev/global/security/oauth2/service/AppOAuth2MemberServiceTest.java @@ -21,6 +21,8 @@ import java.util.HashMap; import java.util.List; import java.util.Map; + +import com.dreamypatisiel.devdevdev.global.security.oauth2.model.UserPrincipal; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -70,11 +72,12 @@ void register() { memberNicknameDictionaryRepository.saveAll(nicknameDictionaryWords); // when - oAuth2MemberService.register(mockOAuth2UserProvider, mockOAuth2User); + UserPrincipal userPrincipal = oAuth2MemberService.register(mockOAuth2UserProvider, mockOAuth2User); // then Member member = memberRepository.findMemberByUserIdAndSocialType(userId, socialType).get(); assertThat(member).isNotNull(); + assertThat(userPrincipal.isNewMember()).isEqualTo(true); } @Test diff --git a/src/test/java/com/dreamypatisiel/devdevdev/global/utils/CookieUtilsTest.java b/src/test/java/com/dreamypatisiel/devdevdev/global/utils/CookieUtilsTest.java index f3fad464..d55d547e 100644 --- a/src/test/java/com/dreamypatisiel/devdevdev/global/utils/CookieUtilsTest.java +++ b/src/test/java/com/dreamypatisiel/devdevdev/global/utils/CookieUtilsTest.java @@ -267,19 +267,22 @@ void configMemberCookie(String inputIsAdmin, String expectedIsAdmin) { Member member = Member.createMemberBy(socialMemberDto); String encodedNickname = URLEncoder.encode(member.getNicknameAsString(), StandardCharsets.UTF_8); String email = member.getEmailAsString(); + boolean isNewMember = true; // when - CookieUtils.configMemberCookie(response, member); + CookieUtils.configMemberCookie(response, member, isNewMember); // then Cookie nicknameCookie = response.getCookie(JwtCookieConstant.DEVDEVDEV_MEMBER_NICKNAME); Cookie emailCookie = response.getCookie(JwtCookieConstant.DEVDEVDEV_MEMBER_EMAIL); Cookie isAdmin = response.getCookie(JwtCookieConstant.DEVDEVDEV_MEMBER_IS_ADMIN); + Cookie isNewMemberCookie = response.getCookie(JwtCookieConstant.DEVDEVDEV_MEMBER_IS_NEW); assertAll( () -> assertThat(nicknameCookie).isNotNull(), () -> assertThat(emailCookie).isNotNull(), - () -> assertThat(isAdmin).isNotNull() + () -> assertThat(isAdmin).isNotNull(), + () -> assertThat(isNewMemberCookie).isNotNull() ); assertAll( @@ -305,6 +308,14 @@ void configMemberCookie(String inputIsAdmin, String expectedIsAdmin) { () -> assertThat(isAdmin.getSecure()).isTrue(), () -> assertThat(isAdmin.isHttpOnly()).isFalse() ); + + assertAll( + () -> assertThat(isNewMemberCookie.getName()).isEqualTo(JwtCookieConstant.DEVDEVDEV_MEMBER_IS_NEW), + () -> assertThat(isNewMemberCookie.getValue()).isEqualTo(String.valueOf(isNewMember)), + () -> assertThat(isNewMemberCookie.getMaxAge()).isEqualTo(CookieUtils.DEFAULT_MAX_AGE), + () -> assertThat(isNewMemberCookie.getSecure()).isTrue(), + () -> assertThat(isNewMemberCookie.isHttpOnly()).isFalse() + ); } private SocialMemberDto createSocialDto(String userId, String name, String nickname, String password, String email,