From 8695497a010cbabd005d21e92ba4fdfdd40f6846 Mon Sep 17 00:00:00 2001 From: JoJaeHyeon Date: Thu, 7 Mar 2024 12:32:17 +0900 Subject: [PATCH 01/16] =?UTF-8?q?chore=20:=20=EC=86=8C=EC=85=9C=EB=A1=9C?= =?UTF-8?q?=EA=B7=B8=EC=9D=B8=20=EC=82=AC=EC=9A=A9=20=EB=B0=A9=EC=8B=9D=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=EC=9C=BC=EB=A1=9C=20=EC=9D=B8=ED=95=9C=20oau?= =?UTF-8?q?th2=EC=9D=98=EC=A1=B4=EC=84=B1=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lime/domains/auth/CustomOauth2User.java | 30 ----- .../domains/auth/dto/OAuthAttributes.java | 81 ------------ .../domains/auth/vo/GoogleOAuth2UserInfo.java | 24 ---- .../domains/auth/vo/KakaoOAuth2UserInfo.java | 41 ------ .../lime/domains/auth/vo/OAuth2UserInfo.java | 18 --- .../config/security/OAuth2UserService.java | 96 -------------- .../handler/OAuth2LoginFailureHandler.java | 24 ---- .../handler/OAuth2LoginSuccessHandler.java | 123 ------------------ 8 files changed, 437 deletions(-) delete mode 100644 lime-api/src/main/java/com/programmers/lime/domains/auth/CustomOauth2User.java delete mode 100644 lime-api/src/main/java/com/programmers/lime/domains/auth/dto/OAuthAttributes.java delete mode 100644 lime-api/src/main/java/com/programmers/lime/domains/auth/vo/GoogleOAuth2UserInfo.java delete mode 100644 lime-api/src/main/java/com/programmers/lime/domains/auth/vo/KakaoOAuth2UserInfo.java delete mode 100644 lime-api/src/main/java/com/programmers/lime/domains/auth/vo/OAuth2UserInfo.java delete mode 100644 lime-api/src/main/java/com/programmers/lime/global/config/security/OAuth2UserService.java delete mode 100644 lime-api/src/main/java/com/programmers/lime/global/config/security/auth/handler/OAuth2LoginFailureHandler.java delete mode 100644 lime-api/src/main/java/com/programmers/lime/global/config/security/auth/handler/OAuth2LoginSuccessHandler.java diff --git a/lime-api/src/main/java/com/programmers/lime/domains/auth/CustomOauth2User.java b/lime-api/src/main/java/com/programmers/lime/domains/auth/CustomOauth2User.java deleted file mode 100644 index b49f401fa..000000000 --- a/lime-api/src/main/java/com/programmers/lime/domains/auth/CustomOauth2User.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.programmers.lime.domains.auth; - -import java.util.Collection; -import java.util.Map; - -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.oauth2.core.user.DefaultOAuth2User; - -import com.programmers.lime.domains.member.domain.vo.Role; - -import lombok.Getter; - -@Getter -public class CustomOauth2User extends DefaultOAuth2User { - - private Long memberId; - private Role role; - - public CustomOauth2User( - final Collection authorities, - final Map attributes, - final String nameAttributeKey, - final Long memberId, - final Role role - ) { - super(authorities, attributes, nameAttributeKey); - this.memberId = memberId; - this.role = role; - } -} diff --git a/lime-api/src/main/java/com/programmers/lime/domains/auth/dto/OAuthAttributes.java b/lime-api/src/main/java/com/programmers/lime/domains/auth/dto/OAuthAttributes.java deleted file mode 100644 index b9b2a33ec..000000000 --- a/lime-api/src/main/java/com/programmers/lime/domains/auth/dto/OAuthAttributes.java +++ /dev/null @@ -1,81 +0,0 @@ -package com.programmers.lime.domains.auth.dto; - -import java.util.Map; -import java.util.UUID; - -import com.programmers.lime.domains.auth.vo.GoogleOAuth2UserInfo; -import com.programmers.lime.domains.auth.vo.KakaoOAuth2UserInfo; -import com.programmers.lime.domains.auth.vo.OAuth2UserInfo; -import com.programmers.lime.domains.member.domain.Member; -import com.programmers.lime.domains.member.domain.vo.Role; -import com.programmers.lime.domains.member.domain.vo.SocialType; -import com.programmers.lime.domains.member.domain.vo.SocialInfo; - -import lombok.Builder; -import lombok.Getter; - -@Getter -public class OAuthAttributes { - - private String nameAttributeKey; // 키가 되는 필드값(pk) - private OAuth2UserInfo oauth2UserInfo; // 소셜 유저 정보 - - @Builder - OAuthAttributes( - final String nameAttributeKey, - final OAuth2UserInfo oauth2UserInfo - ){ - this.nameAttributeKey = nameAttributeKey; - this.oauth2UserInfo = oauth2UserInfo; - } - - public static OAuthAttributes of( - final SocialType socialType, - final String userNameAttributeName, - final Map attributes - ) { - if(socialType == SocialType.KAKAO){ - return ofKakao(userNameAttributeName,attributes); - } - return ofGoogle(userNameAttributeName, attributes); - } - - public Member toEntity( - final SocialType socialType, - final OAuth2UserInfo oauth2UserInfo - ){ - SocialInfo socialInfo = SocialInfo.builder() - .socialId(oauth2UserInfo.getSocialId()) - .email(oauth2UserInfo.getEmail()) - .profileImage(oauth2UserInfo.getProfileImage()) - .role(Role.GUEST) - .socialType(socialType) - .build(); - - long timestamp = System.currentTimeMillis(); - String randomString = String.valueOf(UUID.randomUUID()).replace("-", "").substring(0, 8); - String randomNickname = timestamp + randomString; - - return new Member(socialInfo, randomNickname); - } - - private static OAuthAttributes ofKakao( - final String userNameAttributeName, - final Map attributes - ) { - return OAuthAttributes.builder() - .nameAttributeKey(userNameAttributeName) - .oauth2UserInfo(new KakaoOAuth2UserInfo(attributes)) - .build(); - } - - private static OAuthAttributes ofGoogle( - final String userNameAttributeName, - final Map attributes - ) { - return OAuthAttributes.builder() - .nameAttributeKey(userNameAttributeName) - .oauth2UserInfo(new GoogleOAuth2UserInfo(attributes)) - .build(); - } -} diff --git a/lime-api/src/main/java/com/programmers/lime/domains/auth/vo/GoogleOAuth2UserInfo.java b/lime-api/src/main/java/com/programmers/lime/domains/auth/vo/GoogleOAuth2UserInfo.java deleted file mode 100644 index e649deb23..000000000 --- a/lime-api/src/main/java/com/programmers/lime/domains/auth/vo/GoogleOAuth2UserInfo.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.programmers.lime.domains.auth.vo; - -import java.util.Map; - -public class GoogleOAuth2UserInfo extends OAuth2UserInfo { - public GoogleOAuth2UserInfo(final Map attributes) { - super(attributes); - } - - @Override - public String getSocialId() { - return (String) attributes.get("sub"); - } - - @Override - public String getEmail() { - return null; - } - - @Override - public String getProfileImage() { - return (String) attributes.get("picture"); - } -} diff --git a/lime-api/src/main/java/com/programmers/lime/domains/auth/vo/KakaoOAuth2UserInfo.java b/lime-api/src/main/java/com/programmers/lime/domains/auth/vo/KakaoOAuth2UserInfo.java deleted file mode 100644 index 2702c0c94..000000000 --- a/lime-api/src/main/java/com/programmers/lime/domains/auth/vo/KakaoOAuth2UserInfo.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.programmers.lime.domains.auth.vo; - -import java.util.Map; - -public class KakaoOAuth2UserInfo extends OAuth2UserInfo { - public KakaoOAuth2UserInfo(final Map attributes) { - super(attributes); - } - - @Override - public String getSocialId() { - return String.valueOf(attributes.get("id")); - } - - @Override - public String getEmail() { - Map account = (Map) attributes.get("kakao_account"); - if (account == null) { - return null; - } - - return (String) account.get("email"); - } - - @Override - public String getProfileImage() { - Map account = (Map) attributes.get("kakao_account"); - - if (account == null) { - return null; - } - - Map profile = (Map) account.get("profile"); - - if (profile == null) { - return null; - } - - return (String) profile.get("thumbnail_image_url"); - } -} diff --git a/lime-api/src/main/java/com/programmers/lime/domains/auth/vo/OAuth2UserInfo.java b/lime-api/src/main/java/com/programmers/lime/domains/auth/vo/OAuth2UserInfo.java deleted file mode 100644 index d23aced33..000000000 --- a/lime-api/src/main/java/com/programmers/lime/domains/auth/vo/OAuth2UserInfo.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.programmers.lime.domains.auth.vo; - -import java.util.Map; - -public abstract class OAuth2UserInfo { - - protected Map attributes; - - public OAuth2UserInfo(Map attributes){ - this.attributes = attributes; - } - - public abstract String getSocialId(); - - public abstract String getEmail(); - - public abstract String getProfileImage(); -} diff --git a/lime-api/src/main/java/com/programmers/lime/global/config/security/OAuth2UserService.java b/lime-api/src/main/java/com/programmers/lime/global/config/security/OAuth2UserService.java deleted file mode 100644 index 6645913c9..000000000 --- a/lime-api/src/main/java/com/programmers/lime/global/config/security/OAuth2UserService.java +++ /dev/null @@ -1,96 +0,0 @@ -package com.programmers.lime.global.config.security; - -import java.util.Collections; -import java.util.Map; - -import org.springframework.security.core.authority.SimpleGrantedAuthority; -import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService; -import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest; -import org.springframework.security.oauth2.core.OAuth2AuthenticationException; -import org.springframework.security.oauth2.core.user.OAuth2User; -import org.springframework.stereotype.Service; - -import com.programmers.lime.domains.auth.CustomOauth2User; -import com.programmers.lime.domains.auth.dto.OAuthAttributes; -import com.programmers.lime.domains.member.domain.Member; -import com.programmers.lime.domains.member.implementation.MemberAppender; -import com.programmers.lime.domains.member.implementation.MemberReader; -import com.programmers.lime.domains.member.domain.vo.SocialType; - -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; - -@Slf4j -@Service -@RequiredArgsConstructor -public class OAuth2UserService extends DefaultOAuth2UserService { - - private final MemberAppender memberAppender; - private final MemberReader memberReader; - - @Override - public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException { - log.info("OAuth2UserService 실행"); - OAuth2User oAuth2User = super.loadUser(userRequest); - Map attributes = oAuth2User.getAttributes(); - - /** - * userRequest에서 registrationId 추출 후 registrationId으로 SocialType 저장 - * http://localhost:8080/oauth2/authorization/kakao에서 kakao가 registrationId - * userNameAttributeName은 이후에 nameAttributeKey로 설정된다. - */ - String registrationId = userRequest.getClientRegistration().getRegistrationId(); - SocialType socialType = getSocialType(registrationId); - String userNameAttributeName = userRequest.getClientRegistration() - .getProviderDetails() - .getUserInfoEndpoint() - .getUserNameAttributeName(); - - // socialType에 따라 유저 정보를 통해 OAuthAttributes 객체 생성 - OAuthAttributes extractAttributes = OAuthAttributes.of(socialType, userNameAttributeName, attributes); - - Member member = getMember(extractAttributes, socialType); - - return new CustomOauth2User( - Collections.singleton(new SimpleGrantedAuthority(member.getRole().getKey())), - attributes, - extractAttributes.getNameAttributeKey(), - member.getId(), - member.getRole() - ); - } - - private Member getMember( - final OAuthAttributes attributes, - final SocialType socialType - ){ - Member foundMember = memberReader.readBySocialIdAndSocialType( - attributes.getOauth2UserInfo().getSocialId(), - socialType - ).orElse(null); - - if(foundMember == null){ - return saveMember(attributes, socialType); - } - - return foundMember; - } - - private Member saveMember( - final OAuthAttributes attributes, - final SocialType socialType - ) { - Member member = attributes.toEntity(socialType, attributes.getOauth2UserInfo()); - - return memberAppender.append(member); - } - - private SocialType getSocialType(String registrationId) { - String socialRegistrationId = registrationId.toUpperCase(); - - if(SocialType.KAKAO.equals(SocialType.valueOf(socialRegistrationId))) { - return SocialType.KAKAO; - } - return SocialType.GOOGLE; - } -} diff --git a/lime-api/src/main/java/com/programmers/lime/global/config/security/auth/handler/OAuth2LoginFailureHandler.java b/lime-api/src/main/java/com/programmers/lime/global/config/security/auth/handler/OAuth2LoginFailureHandler.java deleted file mode 100644 index 37d115021..000000000 --- a/lime-api/src/main/java/com/programmers/lime/global/config/security/auth/handler/OAuth2LoginFailureHandler.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.programmers.lime.global.config.security.auth.handler; - -import java.io.IOException; - -import org.springframework.security.core.AuthenticationException; -import org.springframework.security.web.authentication.AuthenticationFailureHandler; -import org.springframework.stereotype.Component; - -import jakarta.servlet.ServletException; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import lombok.extern.slf4j.Slf4j; - -@Slf4j -@Component -public class OAuth2LoginFailureHandler implements AuthenticationFailureHandler { - @Override - public void onAuthenticationFailure(final HttpServletRequest request, final HttpServletResponse response, - final AuthenticationException exception) throws IOException, ServletException { - response.setStatus(HttpServletResponse.SC_BAD_REQUEST); - response.getWriter().write("소셜 로그인 실패! 서버 로그를 확인해주세요."); - log.info("소셜 로그인에 실패했습니다. 에러 메시지 : {}", exception.getMessage()); - } -} diff --git a/lime-api/src/main/java/com/programmers/lime/global/config/security/auth/handler/OAuth2LoginSuccessHandler.java b/lime-api/src/main/java/com/programmers/lime/global/config/security/auth/handler/OAuth2LoginSuccessHandler.java deleted file mode 100644 index 62f14c751..000000000 --- a/lime-api/src/main/java/com/programmers/lime/global/config/security/auth/handler/OAuth2LoginSuccessHandler.java +++ /dev/null @@ -1,123 +0,0 @@ -package com.programmers.lime.global.config.security.auth.handler; - -import static com.programmers.lime.domains.member.api.MemberController.*; -import static org.springframework.http.HttpHeaders.*; - -import java.io.IOException; -import java.net.URLEncoder; - -import org.springframework.http.ResponseCookie; -import org.springframework.security.core.Authentication; -import org.springframework.security.web.authentication.AuthenticationSuccessHandler; -import org.springframework.stereotype.Component; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.programmers.lime.domains.member.domain.Member; -import com.programmers.lime.domains.member.domain.vo.Role; -import com.programmers.lime.domains.member.implementation.MemberReader; -import com.programmers.lime.error.BusinessException; -import com.programmers.lime.error.ErrorCode; -import com.programmers.lime.domains.auth.CustomOauth2User; -import com.programmers.lime.global.config.security.jwt.JwtService; - -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; - -@Slf4j -@Component -@RequiredArgsConstructor -public class OAuth2LoginSuccessHandler implements AuthenticationSuccessHandler { - - private final JwtService jwtService; - private final MemberReader memberReader; - - @Override - public void onAuthenticationSuccess( - final HttpServletRequest request, - final HttpServletResponse response, - final Authentication authentication - ) { - log.info("Oauth2 로그인 성공"); - - try { - CustomOauth2User oauth2User = (CustomOauth2User)authentication.getPrincipal(); - - if (oauth2User.getRole() == Role.GUEST) { - log.info("기본 인적사항은 업데이트 하지 않은 유저"); - signUpSuccess(response, oauth2User); - } else { - log.info("기본 인적사항이 등록된 유저"); - loginSuccess(response, oauth2User); - } - } catch (Exception e) { - throw new BusinessException(ErrorCode.INTERNAL_SERVER_ERROR); - } - } - - private void signUpSuccess( - final HttpServletResponse response, - final CustomOauth2User oauth2User - ) { - String accessToken = jwtService.generateAccessToken(String.valueOf(oauth2User.getMemberId())); - - sendAccessToken(response, accessToken); - } - - private void loginSuccess( - final HttpServletResponse response, - final CustomOauth2User oauth2User - ) { - Long memberId = oauth2User.getMemberId(); - String accessToken = jwtService.generateAccessToken(String.valueOf(memberId)); - String refreshToken = jwtService.generateRefreshToken(); - - Member member = memberReader.read(memberId); - - sendAccessAndRefreshToken(response, member, accessToken, refreshToken); - } - - private void sendAccessToken( - final HttpServletResponse response, - final String accessToken - ) { - response.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY); - response.setHeader("Location", "http://localhost:3000/join"); - try { - response.sendRedirect("http://localhost:3000/join" + "?accessToken=" + accessToken); - } catch (IOException e){ - throw new BusinessException(ErrorCode.INTERNAL_SERVER_ERROR); - } - log.info("재발급된 Access Token : {}", accessToken); - } - - private void sendAccessAndRefreshToken( - final HttpServletResponse response, - final Member member, - final String accessToken, - final String refreshToken - ){ - response.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY); - response.setHeader("Location", "http://localhost:3000/"); - try { - String redirectURL = URLEncoder.encode(member.getNickname(), "UTF-8"); - response.sendRedirect("http://localhost:3000/" + "?accessToken=" + accessToken - + "&memberId=" + member.getId() + "&nickname=" + redirectURL); - } catch (IOException e){ - throw new BusinessException(ErrorCode.INTERNAL_SERVER_ERROR); - } - - final ResponseCookie cookie = ResponseCookie.from("refresh-token", refreshToken) - .maxAge(COOKIE_AGE_SECONDS) - .secure(true) - .httpOnly(true) - .sameSite("None") - .path("/") - .build(); - - response.addHeader(SET_COOKIE, String.valueOf(cookie)); - - log.info("Access Token, Refresh 설정 완료"); - } -} From 285f2a4e2a31b7fee14a0cdb924d923af92f7395 Mon Sep 17 00:00:00 2001 From: JoJaeHyeon Date: Thu, 7 Mar 2024 12:33:38 +0900 Subject: [PATCH 02/16] =?UTF-8?q?feat=20:=20=EC=B9=B4=EC=B9=B4=EC=98=A4=20?= =?UTF-8?q?=EC=86=8C=EC=85=9C=EB=A1=9C=EA=B7=B8=EC=9D=B8=20code=EB=A5=BC?= =?UTF-8?q?=20=EB=B0=9B=EC=95=84=20=EC=B2=98=EB=A6=AC=ED=95=98=EB=8A=94=20?= =?UTF-8?q?=EB=B9=84=EC=A6=88=EB=8B=88=EC=8A=A4=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lime/domains/auth/api/AuthController.java | 28 ++++++++++++ .../auth/application/OAuthUserService.java | 45 +++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 lime-api/src/main/java/com/programmers/lime/domains/auth/api/AuthController.java create mode 100644 lime-api/src/main/java/com/programmers/lime/domains/auth/application/OAuthUserService.java diff --git a/lime-api/src/main/java/com/programmers/lime/domains/auth/api/AuthController.java b/lime-api/src/main/java/com/programmers/lime/domains/auth/api/AuthController.java new file mode 100644 index 000000000..dfcf2727c --- /dev/null +++ b/lime-api/src/main/java/com/programmers/lime/domains/auth/api/AuthController.java @@ -0,0 +1,28 @@ +package com.programmers.lime.domains.auth.api; + +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.programmers.lime.domains.auth.application.OAuthUserService; +import com.programmers.lime.domains.member.api.dto.response.MemberLoginResponse; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@RequiredArgsConstructor +@RequestMapping("/api") +@RestController +public class AuthController { + + private final OAuthUserService oauthUserService; + + @GetMapping("/auth/kakao/callback") + public ResponseEntity loginKakao( + @RequestParam final String code + ) { + return ResponseEntity.ok(oauthUserService.login(code)); + } +} diff --git a/lime-api/src/main/java/com/programmers/lime/domains/auth/application/OAuthUserService.java b/lime-api/src/main/java/com/programmers/lime/domains/auth/application/OAuthUserService.java new file mode 100644 index 000000000..2dc8c4476 --- /dev/null +++ b/lime-api/src/main/java/com/programmers/lime/domains/auth/application/OAuthUserService.java @@ -0,0 +1,45 @@ +package com.programmers.lime.domains.auth.application; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.programmers.lime.domains.auth.api.dto.KakaoMemberResponse; +import com.programmers.lime.domains.member.api.dto.response.MemberLoginResponse; +import com.programmers.lime.domains.member.domain.Member; +import com.programmers.lime.domains.member.domain.vo.SocialType; +import com.programmers.lime.domains.member.implementation.MemberAppender; +import com.programmers.lime.domains.member.implementation.MemberReader; +import com.programmers.lime.global.config.security.jwt.JwtService; + +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +public class OAuthUserService { + + private final KakaoOAuthClient kakaoOAuthClient; + private final MemberAppender memberAppender; + private final MemberReader memberReader; + private final JwtService jwtService; + + @Transactional + public MemberLoginResponse login(String code) { + String kakaoAccessToken = kakaoOAuthClient.getAccessToken(code); + KakaoMemberResponse response = kakaoOAuthClient.getMemberInfo(kakaoAccessToken); + + Member foundMember = memberReader.readBySocialIdAndSocialType( + response.id(), + SocialType.KAKAO + ).orElseGet(() -> saveMember(response)); + + String accessToken = jwtService.generateAccessToken(String.valueOf(foundMember.getId())); + String refreshToken = jwtService.generateRefreshToken(); + + return MemberLoginResponse.from(foundMember, accessToken, refreshToken); + } + + private Member saveMember(final KakaoMemberResponse response) { + return memberAppender.append(response.toEntity()); + } + +} From 17d4d60991f592936bb310d87498d642d4207f97 Mon Sep 17 00:00:00 2001 From: JoJaeHyeon Date: Thu, 7 Mar 2024 12:34:30 +0900 Subject: [PATCH 03/16] =?UTF-8?q?refactor=20:=20=EC=86=8C=EC=85=9C=20id=20?= =?UTF-8?q?long=ED=83=80=EC=9E=85=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../member/api/dto/response/MemberLoginResponse.java | 9 ++++++--- .../programmers/lime/domains/member/domain/Member.java | 3 ++- .../lime/domains/member/domain/vo/SocialInfo.java | 4 ++-- .../lime/domains/member/implementation/MemberReader.java | 7 ++++++- .../lime/domains/member/repository/MemberRepository.java | 2 +- 5 files changed, 17 insertions(+), 8 deletions(-) diff --git a/lime-api/src/main/java/com/programmers/lime/domains/member/api/dto/response/MemberLoginResponse.java b/lime-api/src/main/java/com/programmers/lime/domains/member/api/dto/response/MemberLoginResponse.java index 8d9fc5116..e58a59106 100644 --- a/lime-api/src/main/java/com/programmers/lime/domains/member/api/dto/response/MemberLoginResponse.java +++ b/lime-api/src/main/java/com/programmers/lime/domains/member/api/dto/response/MemberLoginResponse.java @@ -5,16 +5,19 @@ public record MemberLoginResponse( Long memberId, String nickname, - String accessToken + String accessToken, + String refreshToken ) { public static MemberLoginResponse from( final Member member, - final String accessToken + final String accessToken, + final String refreshToken ) { return new MemberLoginResponse( member.getId(), member.getNickname(), - accessToken + accessToken, + refreshToken ); } } diff --git a/lime-domain/src/main/java/com/programmers/lime/domains/member/domain/Member.java b/lime-domain/src/main/java/com/programmers/lime/domains/member/domain/Member.java index fb222090f..1412cb9f7 100644 --- a/lime-domain/src/main/java/com/programmers/lime/domains/member/domain/Member.java +++ b/lime-domain/src/main/java/com/programmers/lime/domains/member/domain/Member.java @@ -20,6 +20,7 @@ import jakarta.persistence.Id; import jakarta.persistence.Table; import lombok.AccessLevel; +import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; @@ -60,7 +61,7 @@ public Member( this.status = MemberStatus.ACTIVE; } - public String getSocialId() { + public Long getSocialId() { return socialInfo.getSocialId(); } diff --git a/lime-domain/src/main/java/com/programmers/lime/domains/member/domain/vo/SocialInfo.java b/lime-domain/src/main/java/com/programmers/lime/domains/member/domain/vo/SocialInfo.java index d38aebdd5..4d758122f 100644 --- a/lime-domain/src/main/java/com/programmers/lime/domains/member/domain/vo/SocialInfo.java +++ b/lime-domain/src/main/java/com/programmers/lime/domains/member/domain/vo/SocialInfo.java @@ -15,7 +15,7 @@ public class SocialInfo { @Column(name = "social_id") - private String socialId; + private Long socialId; @Column(name = "email", nullable = false) private String email; @@ -33,7 +33,7 @@ public class SocialInfo { @Builder public SocialInfo( - final String socialId, + final Long socialId, final String email, final String profileImage, final SocialType socialType, diff --git a/lime-domain/src/main/java/com/programmers/lime/domains/member/implementation/MemberReader.java b/lime-domain/src/main/java/com/programmers/lime/domains/member/implementation/MemberReader.java index 15bdfc71d..9caa3fa36 100644 --- a/lime-domain/src/main/java/com/programmers/lime/domains/member/implementation/MemberReader.java +++ b/lime-domain/src/main/java/com/programmers/lime/domains/member/implementation/MemberReader.java @@ -20,7 +20,9 @@ import com.programmers.lime.error.ErrorCode; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +@Slf4j @Component @RequiredArgsConstructor @Transactional(readOnly = true) @@ -58,7 +60,10 @@ public MyPage readMyPage(final Member member) { return new MyPage(memberProfile, bucketProfiles, inventoryProfiles); } - public Optional readBySocialIdAndSocialType(String socialId, SocialType socialType) { + public Optional readBySocialIdAndSocialType( + final Long socialId, + final SocialType socialType + ) { return memberRepository.findBySocialInfoSocialIdAndSocialInfoSocialType(socialId, socialType); } } diff --git a/lime-domain/src/main/java/com/programmers/lime/domains/member/repository/MemberRepository.java b/lime-domain/src/main/java/com/programmers/lime/domains/member/repository/MemberRepository.java index 7c1e95b6c..3e600e5d6 100644 --- a/lime-domain/src/main/java/com/programmers/lime/domains/member/repository/MemberRepository.java +++ b/lime-domain/src/main/java/com/programmers/lime/domains/member/repository/MemberRepository.java @@ -15,7 +15,7 @@ public interface MemberRepository extends JpaRepository { Optional findByNicknameNickname(final String nickname); Optional findBySocialInfoSocialIdAndSocialInfoSocialType( - final String socialId, + final Long socialId, final SocialType socialType ); } From 098c3632d158ff25706ada52c23533aa3c480362 Mon Sep 17 00:00:00 2001 From: JoJaeHyeon Date: Thu, 7 Mar 2024 12:34:58 +0900 Subject: [PATCH 04/16] =?UTF-8?q?feat=20:=20=EC=B9=B4=EC=B9=B4=EC=98=A4=20?= =?UTF-8?q?=EC=A0=84=EC=9A=A9=20=ED=86=A0=ED=81=B0=20=EC=9A=94=EC=B2=AD=20?= =?UTF-8?q?=EB=B0=8F=20=EC=88=98=EC=8B=A0=20dto=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../auth/api/dto/KakaoMemberResponse.java | 47 ++++++++++++ .../auth/api/dto/KakaoOAuthLoginInfo.java | 12 ++++ .../api/dto/OAuthAccessTokenResponse.java | 14 ++++ .../auth/application/KakaoOAuthClient.java | 71 +++++++++++++++++++ 4 files changed, 144 insertions(+) create mode 100644 lime-api/src/main/java/com/programmers/lime/domains/auth/api/dto/KakaoMemberResponse.java create mode 100644 lime-api/src/main/java/com/programmers/lime/domains/auth/api/dto/KakaoOAuthLoginInfo.java create mode 100644 lime-api/src/main/java/com/programmers/lime/domains/auth/api/dto/OAuthAccessTokenResponse.java create mode 100644 lime-api/src/main/java/com/programmers/lime/domains/auth/application/KakaoOAuthClient.java diff --git a/lime-api/src/main/java/com/programmers/lime/domains/auth/api/dto/KakaoMemberResponse.java b/lime-api/src/main/java/com/programmers/lime/domains/auth/api/dto/KakaoMemberResponse.java new file mode 100644 index 000000000..6b79b45f1 --- /dev/null +++ b/lime-api/src/main/java/com/programmers/lime/domains/auth/api/dto/KakaoMemberResponse.java @@ -0,0 +1,47 @@ +package com.programmers.lime.domains.auth.api.dto; + +import static com.programmers.lime.domains.member.domain.vo.SocialType.*; + +import java.util.UUID; + +import com.fasterxml.jackson.databind.PropertyNamingStrategies; +import com.fasterxml.jackson.databind.annotation.JsonNaming; +import com.programmers.lime.domains.member.domain.Member; +import com.programmers.lime.domains.member.domain.vo.Role; +import com.programmers.lime.domains.member.domain.vo.SocialInfo; + +@JsonNaming(value = PropertyNamingStrategies.SnakeCaseStrategy.class) +public record KakaoMemberResponse( + Long id, //카카오 소셜 id + + KakaoAccount kakaoAccount + +) { + @JsonNaming(value = PropertyNamingStrategies.SnakeCaseStrategy.class) + public record KakaoAccount( + String email, + Profile profile + ) { + @JsonNaming(value = PropertyNamingStrategies.SnakeCaseStrategy.class) + public record Profile( + String profileImageUrl + ) { + } + } + + public Member toEntity(){ + SocialInfo socialInfo = SocialInfo.builder() + .socialId(this.id) + .email(this.kakaoAccount.email) + .profileImage(this.kakaoAccount.profile.profileImageUrl) + .role(Role.GUEST) + .socialType(KAKAO) + .build(); + + long timestamp = System.currentTimeMillis(); + String randomString = String.valueOf(UUID.randomUUID()).replace("-", "").substring(0, 8); + String randomNickname = timestamp + randomString; + + return new Member(socialInfo, randomNickname); + } +} \ No newline at end of file diff --git a/lime-api/src/main/java/com/programmers/lime/domains/auth/api/dto/KakaoOAuthLoginInfo.java b/lime-api/src/main/java/com/programmers/lime/domains/auth/api/dto/KakaoOAuthLoginInfo.java new file mode 100644 index 000000000..ab9108ae5 --- /dev/null +++ b/lime-api/src/main/java/com/programmers/lime/domains/auth/api/dto/KakaoOAuthLoginInfo.java @@ -0,0 +1,12 @@ +package com.programmers.lime.domains.auth.api.dto; + +import org.springframework.boot.context.properties.ConfigurationProperties; + +@ConfigurationProperties(prefix = "oauth.kakao.login") +public record KakaoOAuthLoginInfo( + String grantType, + String clientId, + String clientSecret, + String redirectUri +) { +} \ No newline at end of file diff --git a/lime-api/src/main/java/com/programmers/lime/domains/auth/api/dto/OAuthAccessTokenResponse.java b/lime-api/src/main/java/com/programmers/lime/domains/auth/api/dto/OAuthAccessTokenResponse.java new file mode 100644 index 000000000..d70fdfbfc --- /dev/null +++ b/lime-api/src/main/java/com/programmers/lime/domains/auth/api/dto/OAuthAccessTokenResponse.java @@ -0,0 +1,14 @@ +package com.programmers.lime.domains.auth.api.dto; + +import com.fasterxml.jackson.databind.PropertyNamingStrategies; +import com.fasterxml.jackson.databind.annotation.JsonNaming; + +@JsonNaming(value = PropertyNamingStrategies.SnakeCaseStrategy.class) +public record OAuthAccessTokenResponse( + String tokenType, + String accessToken, + Integer expiresIn, + String refreshToken, + Integer refreshTokenExpiresIn +) { +} \ No newline at end of file diff --git a/lime-api/src/main/java/com/programmers/lime/domains/auth/application/KakaoOAuthClient.java b/lime-api/src/main/java/com/programmers/lime/domains/auth/application/KakaoOAuthClient.java new file mode 100644 index 000000000..aa17bc63f --- /dev/null +++ b/lime-api/src/main/java/com/programmers/lime/domains/auth/application/KakaoOAuthClient.java @@ -0,0 +1,71 @@ +package com.programmers.lime.domains.auth.application; + +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Component; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.RestTemplate; + +import com.programmers.lime.domains.auth.api.dto.KakaoMemberResponse; +import com.programmers.lime.domains.auth.api.dto.KakaoOAuthLoginInfo; +import com.programmers.lime.domains.auth.api.dto.OAuthAccessTokenResponse; + +import lombok.RequiredArgsConstructor; + +@Component +@RequiredArgsConstructor +public class KakaoOAuthClient { + + private static final RestTemplate restTemplate = new RestTemplate(); + private final KakaoOAuthLoginInfo kakaoOAuthLoginInfo; + + public String getAccessToken(final String code) { + MultiValueMap loginInfoRequest = makeKakaoLoginInfo(code); + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); + + HttpEntity> httpEntity = new HttpEntity<>(loginInfoRequest, headers); + + OAuthAccessTokenResponse response = restTemplate.postForEntity( + "https://kauth.kakao.com/oauth/token", + httpEntity, + OAuthAccessTokenResponse.class + ).getBody(); + + return response.accessToken(); + } + + private MultiValueMap makeKakaoLoginInfo(final String code) { + MultiValueMap loginInfoRequest = new LinkedMultiValueMap<>(); + + loginInfoRequest.add("grant_type", kakaoOAuthLoginInfo.grantType()); + loginInfoRequest.add("client_id", kakaoOAuthLoginInfo.clientId()); + loginInfoRequest.add("client_secret", kakaoOAuthLoginInfo.clientSecret()); + loginInfoRequest.add("redirect_uri", kakaoOAuthLoginInfo.redirectUri()); + loginInfoRequest.add("code", code); + + return loginInfoRequest; + } + + public KakaoMemberResponse getMemberInfo(final String accessToken) { + HttpHeaders headers = new HttpHeaders(); + headers.setBearerAuth(accessToken); + headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); + + HttpEntity request = new HttpEntity<>(headers); + + KakaoMemberResponse response = restTemplate.exchange( + "https://kapi.kakao.com/v2/user/me", + HttpMethod.GET, + request, + KakaoMemberResponse.class + ).getBody(); + + return response; + } + + +} From 71911d1846449e30a8cbbbecd7cf9414dfff0194 Mon Sep 17 00:00:00 2001 From: JoJaeHyeon Date: Thu, 7 Mar 2024 12:35:37 +0900 Subject: [PATCH 05/16] =?UTF-8?q?refactor:=20=EC=B9=B4=EC=B9=B4=EC=98=A4?= =?UTF-8?q?=20=EC=86=8C=EC=85=9C=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=EB=B0=A9?= =?UTF-8?q?=EC=8B=9D=20=EB=B3=80=EA=B2=BD=EC=9C=BC=EB=A1=9C=20=EC=9D=B8?= =?UTF-8?q?=ED=95=9C=20security=20=EC=84=A4=EC=A0=95=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../config/security/MemberSecurity.java | 3 +- .../security/SecurityConfiguration.java | 37 ++++------------ .../security/jwt/JwtAuthenticationFilter.java | 43 ++++++++++++++++--- 3 files changed, 47 insertions(+), 36 deletions(-) diff --git a/lime-api/src/main/java/com/programmers/lime/global/config/security/MemberSecurity.java b/lime-api/src/main/java/com/programmers/lime/global/config/security/MemberSecurity.java index 15dc2c2e8..988312943 100644 --- a/lime-api/src/main/java/com/programmers/lime/global/config/security/MemberSecurity.java +++ b/lime-api/src/main/java/com/programmers/lime/global/config/security/MemberSecurity.java @@ -8,6 +8,7 @@ import org.springframework.security.core.userdetails.UserDetails; import com.programmers.lime.domains.member.domain.Member; +import com.programmers.lime.domains.member.domain.vo.Role; import lombok.RequiredArgsConstructor; @@ -18,7 +19,7 @@ public class MemberSecurity implements UserDetails { @Override public Collection getAuthorities() { - return List.of(new SimpleGrantedAuthority(member.getRole().name())); + return List.of(new SimpleGrantedAuthority("ROLE_" + member.getRole().name())); } @Override diff --git a/lime-api/src/main/java/com/programmers/lime/global/config/security/SecurityConfiguration.java b/lime-api/src/main/java/com/programmers/lime/global/config/security/SecurityConfiguration.java index a48ae27c3..38af0b7ea 100644 --- a/lime-api/src/main/java/com/programmers/lime/global/config/security/SecurityConfiguration.java +++ b/lime-api/src/main/java/com/programmers/lime/global/config/security/SecurityConfiguration.java @@ -12,18 +12,13 @@ import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.web.SecurityFilterChain; -import org.springframework.security.web.authentication.AuthenticationFailureHandler; -import org.springframework.security.web.authentication.AuthenticationSuccessHandler; +import org.springframework.security.web.access.AccessDeniedHandler; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.CorsConfigurationSource; import org.springframework.web.cors.UrlBasedCorsConfigurationSource; -import com.programmers.lime.domains.member.implementation.MemberReader; -import com.programmers.lime.global.config.security.auth.handler.OAuth2LoginFailureHandler; -import com.programmers.lime.global.config.security.auth.handler.OAuth2LoginSuccessHandler; import com.programmers.lime.global.config.security.jwt.JwtAuthenticationFilter; -import com.programmers.lime.global.config.security.jwt.JwtService; import lombok.RequiredArgsConstructor; @@ -32,11 +27,9 @@ @RequiredArgsConstructor public class SecurityConfiguration { - private final OAuth2UserService oAuth2UserService; //추가 - private final JwtService jwtService; // 추가 - private final MemberReader memberReader; private final JwtAuthenticationFilter jwtAuthenticationFilter; private final AuthenticationProvider authenticationProvider; + private final AccessDeniedHandler accessDeniedHandler; @Bean public SecurityFilterChain securityFilterChain(final HttpSecurity http) throws Exception { @@ -48,12 +41,8 @@ public SecurityFilterChain securityFilterChain(final HttpSecurity http) throws E .requestMatchers("/swagger-ui/**").permitAll() .requestMatchers("/swagger*/**").permitAll() .requestMatchers("/v3/api-docs/**").permitAll() - .requestMatchers("/").permitAll() - .requestMatchers("/api/members/signup").permitAll() - .requestMatchers("/api/members/login").permitAll() .requestMatchers("/api/members/check/nickname").permitAll() - .requestMatchers("/api/members/check/email").permitAll() .requestMatchers("/api/members/mypage/{nickname}").permitAll() .requestMatchers("/api/members/refresh").permitAll() @@ -78,31 +67,21 @@ public SecurityFilterChain securityFilterChain(final HttpSecurity http) throws E .requestMatchers("/api/hobbies").permitAll() .requestMatchers("/login").permitAll() .requestMatchers("/actuator/**").permitAll() - .anyRequest().authenticated() + .requestMatchers("/api/auth/kakao/callback").permitAll() + + .anyRequest().hasRole("USER") + ) .sessionManagement(session -> session .sessionCreationPolicy(SessionCreationPolicy.STATELESS) ) .authenticationProvider(authenticationProvider) - .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class); - - http.oauth2Login(oauth2Configurer -> oauth2Configurer - .successHandler(successHandler()) - .failureHandler(failureHandler()) - .userInfoEndpoint(userInfoEndpointConfig -> userInfoEndpointConfig.userService(oAuth2UserService))); + .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class) + .exceptionHandling((exceptions) -> exceptions.accessDeniedHandler(accessDeniedHandler)); return http.build(); } - @Bean - public AuthenticationFailureHandler failureHandler() { - return new OAuth2LoginFailureHandler(); - } - - @Bean - public AuthenticationSuccessHandler successHandler() { - return new OAuth2LoginSuccessHandler(jwtService, memberReader); - } @Bean public CorsConfigurationSource corsConfigurationSource() { diff --git a/lime-api/src/main/java/com/programmers/lime/global/config/security/jwt/JwtAuthenticationFilter.java b/lime-api/src/main/java/com/programmers/lime/global/config/security/jwt/JwtAuthenticationFilter.java index 99791cd77..6204a3122 100644 --- a/lime-api/src/main/java/com/programmers/lime/global/config/security/jwt/JwtAuthenticationFilter.java +++ b/lime-api/src/main/java/com/programmers/lime/global/config/security/jwt/JwtAuthenticationFilter.java @@ -1,26 +1,36 @@ package com.programmers.lime.global.config.security.jwt; import java.io.IOException; +import java.util.Collection; import java.util.List; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; import org.springframework.stereotype.Component; import org.springframework.web.filter.OncePerRequestFilter; import org.springframework.web.servlet.HandlerExceptionResolver; +import com.programmers.lime.domains.member.domain.Member; +import com.programmers.lime.domains.member.implementation.MemberReader; +import com.programmers.lime.global.config.security.MemberSecurity; + import io.jsonwebtoken.JwtException; import jakarta.servlet.FilterChain; +import jakarta.servlet.RequestDispatcher; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import lombok.NonNull; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +@Slf4j @Component @RequiredArgsConstructor public class JwtAuthenticationFilter extends OncePerRequestFilter { @@ -29,6 +39,7 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter { private final JwtService jwtService; private final HandlerExceptionResolver handlerExceptionResolver; + private final UserDetailsService userDetailsService; @Override protected void doFilterInternal( @@ -39,20 +50,25 @@ protected void doFilterInternal( final String requestUri = request.getRequestURI(); final String authHeader = request.getHeader("Authorization"); final String jwt; - final String memberId; if (requestUri.equals("/api/members/refresh") || authHeader == null || !authHeader.startsWith("Bearer ")) { filterChain.doFilter(request, response); return; } - jwt = authHeader.substring(TOKEN_BEGIN_INDEX); try { if (SecurityContextHolder.getContext().getAuthentication() == null && jwtService.isAccessTokenValid(jwt)) { - memberId = jwtService.extractUsername(jwt); - + final String memberId = jwtService.extractUsername(jwt); final UserDetails principal = makePrincipal(memberId); + + // if(needsProfileUpdate(principal)){ + // // response.setHeader("Location","http://localhost:8080/join"); + // // response.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY); + // // response.sendRedirect("http://localhost:8080/join"); + // + // } + final UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken( principal, null, @@ -69,7 +85,22 @@ protected void doFilterInternal( } } - private static UserDetails makePrincipal(final String memberId) { - return new User(memberId, "", List.of(new SimpleGrantedAuthority("ROLE_USER"))); + // private static boolean needsProfileUpdate(final UserDetails principal) { + // Collection authorities = principal.getAuthorities(); + // for(GrantedAuthority authority : authorities){ + // String role = authority.getAuthority(); + // if(role.equals("ROLE_GUEST")){ + // return true; + // } + // } + // return false; + // } + + private UserDetails makePrincipal(final String memberId) { + return userDetailsService.loadUserByUsername(memberId); } + + // private static UserDetails makePrincipal(final String memberId) { + // return new User(memberId, "", List.of(new SimpleGrantedAuthority("ROLE_USER"))); + // } } From e145506a0c7b036af67f3ecafd7e520b7d18d06e Mon Sep 17 00:00:00 2001 From: JoJaeHyeon Date: Thu, 7 Mar 2024 12:35:53 +0900 Subject: [PATCH 06/16] =?UTF-8?q?refactor=20:=20property=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=EB=A1=9C=20=EC=9D=B8=ED=95=9C=20=EC=8A=A4=EC=BA=94=20?= =?UTF-8?q?=EB=B2=94=EC=9C=84=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/programmers/lime/LimeApplication.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lime-api/src/main/java/com/programmers/lime/LimeApplication.java b/lime-api/src/main/java/com/programmers/lime/LimeApplication.java index 6e2cd209c..2ccb7e73b 100644 --- a/lime-api/src/main/java/com/programmers/lime/LimeApplication.java +++ b/lime-api/src/main/java/com/programmers/lime/LimeApplication.java @@ -7,7 +7,7 @@ @SpringBootApplication @EnableScheduling -@ConfigurationPropertiesScan("com.programmers.lime.global.config.security.jwt") +@ConfigurationPropertiesScan({"com.programmers.lime.global.config.security.jwt", "com.programmers.lime.domains.auth"}) public class LimeApplication { public static void main(String[] args) { From 5d9ba7da3391d681e9186870117123d12ed54739 Mon Sep 17 00:00:00 2001 From: JoJaeHyeon Date: Thu, 7 Mar 2024 12:36:04 +0900 Subject: [PATCH 07/16] =?UTF-8?q?chore=20:=20=EA=B0=9C=ED=96=89=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/programmers/lime/domains/item/api/ItemController.java | 1 - 1 file changed, 1 deletion(-) diff --git a/lime-api/src/main/java/com/programmers/lime/domains/item/api/ItemController.java b/lime-api/src/main/java/com/programmers/lime/domains/item/api/ItemController.java index e22f8eb24..ca8136ad6 100644 --- a/lime-api/src/main/java/com/programmers/lime/domains/item/api/ItemController.java +++ b/lime-api/src/main/java/com/programmers/lime/domains/item/api/ItemController.java @@ -42,7 +42,6 @@ public class ItemController { @Operation(summary = "아이템 등록", description = "ItemEnrollRequest 을 이용하여 아이템을 등록합니다.") @PostMapping("/enroll") - public ResponseEntity enrollItem(@Valid @RequestBody final ItemEnrollRequest request) { Long enrolledItemId = itemEnrollService.enrollItem(request.toEnrollItemServiceRequest()); ItemEnrollResponse response = new ItemEnrollResponse(enrolledItemId); From 9c935ddb89c8f787feacd13ca0ec87e85702ff25 Mon Sep 17 00:00:00 2001 From: JoJaeHyeon Date: Thu, 7 Mar 2024 12:37:09 +0900 Subject: [PATCH 08/16] =?UTF-8?q?fix=20:=20gradle=20=EC=86=8C=EC=85=9C?= =?UTF-8?q?=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=EC=9D=98=EC=A1=B4=EC=84=B1=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0=20=EB=B0=8F=20=ED=94=84=EB=A1=9C=ED=8D=BC?= =?UTF-8?q?=ED=8B=B0=20=EC=A0=81=EC=9A=A9=20=EC=9D=98=EC=A1=B4=EC=84=B1=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lime-api/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lime-api/build.gradle b/lime-api/build.gradle index 4e741d780..03cfd3e0e 100644 --- a/lime-api/build.gradle +++ b/lime-api/build.gradle @@ -40,8 +40,8 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-cache' implementation "com.github.ben-manes.caffeine:caffeine:3.1.8" - // oauth2 - implementation 'org.springframework.boot:spring-boot-starter-oauth2-client' + // configuration processor + annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor' } jar { From 79aa60c27c5c53380ef37b649cec23a2fbad4482 Mon Sep 17 00:00:00 2001 From: JoJaeHyeon Date: Thu, 7 Mar 2024 12:37:34 +0900 Subject: [PATCH 09/16] =?UTF-8?q?chore=20:=20=EA=B0=81=EC=A2=85=20handler,?= =?UTF-8?q?=20entrypoint=20=EC=8B=9C=EB=8F=84=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../security/AccessDeniedHandlerImpl.java | 24 +++++++++++++++++++ .../security/ApplicationConfiguration.java | 4 ++-- .../AuthenticationEntryPointImpl.java | 21 ++++++++++++++++ 3 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 lime-api/src/main/java/com/programmers/lime/global/config/security/AccessDeniedHandlerImpl.java create mode 100644 lime-api/src/main/java/com/programmers/lime/global/config/security/AuthenticationEntryPointImpl.java diff --git a/lime-api/src/main/java/com/programmers/lime/global/config/security/AccessDeniedHandlerImpl.java b/lime-api/src/main/java/com/programmers/lime/global/config/security/AccessDeniedHandlerImpl.java new file mode 100644 index 000000000..f2296927b --- /dev/null +++ b/lime-api/src/main/java/com/programmers/lime/global/config/security/AccessDeniedHandlerImpl.java @@ -0,0 +1,24 @@ +package com.programmers.lime.global.config.security; + +import java.io.IOException; + +import org.springframework.security.access.AccessDeniedException; +import org.springframework.security.web.access.AccessDeniedHandler; +import org.springframework.stereotype.Component; + +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +@Component +public class AccessDeniedHandlerImpl implements AccessDeniedHandler { + @Override + public void handle( + final HttpServletRequest request, + final HttpServletResponse response, + final AccessDeniedException accessDeniedException + ) throws IOException, ServletException { + response.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY); + response.sendRedirect("/join"); + } +} diff --git a/lime-api/src/main/java/com/programmers/lime/global/config/security/ApplicationConfiguration.java b/lime-api/src/main/java/com/programmers/lime/global/config/security/ApplicationConfiguration.java index 4f122d82d..18ddf4104 100644 --- a/lime-api/src/main/java/com/programmers/lime/global/config/security/ApplicationConfiguration.java +++ b/lime-api/src/main/java/com/programmers/lime/global/config/security/ApplicationConfiguration.java @@ -23,8 +23,8 @@ public class ApplicationConfiguration { @Bean public UserDetailsService userDetailsService() { - return username -> { - Member member = memberReader.read(Long.valueOf(username)); + return memberId -> { + Member member = memberReader.read(Long.valueOf(memberId)); return new MemberSecurity(member); }; diff --git a/lime-api/src/main/java/com/programmers/lime/global/config/security/AuthenticationEntryPointImpl.java b/lime-api/src/main/java/com/programmers/lime/global/config/security/AuthenticationEntryPointImpl.java new file mode 100644 index 000000000..478bf25a2 --- /dev/null +++ b/lime-api/src/main/java/com/programmers/lime/global/config/security/AuthenticationEntryPointImpl.java @@ -0,0 +1,21 @@ +package com.programmers.lime.global.config.security; + +import java.io.IOException; + +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.AuthenticationEntryPoint; +import org.springframework.stereotype.Component; + +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +@Component +public class AuthenticationEntryPointImpl implements AuthenticationEntryPoint { + @Override + public void commence(final HttpServletRequest request, final HttpServletResponse response, + final AuthenticationException authException) throws IOException, ServletException { + response.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY); + response.sendRedirect("/join"); + } +} From 9dd6d048f0576aab8555dc71698e457f26d1f4e3 Mon Sep 17 00:00:00 2001 From: JoJaeHyeon Date: Fri, 8 Mar 2024 13:49:07 +0900 Subject: [PATCH 10/16] =?UTF-8?q?chore=20:=20=ED=8C=8C=EC=9D=BC=20?= =?UTF-8?q?=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../config/security/{ => handler}/AccessDeniedHandlerImpl.java | 2 +- .../security/{ => handler}/AuthenticationEntryPointImpl.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename lime-api/src/main/java/com/programmers/lime/global/config/security/{ => handler}/AccessDeniedHandlerImpl.java (92%) rename lime-api/src/main/java/com/programmers/lime/global/config/security/{ => handler}/AuthenticationEntryPointImpl.java (92%) diff --git a/lime-api/src/main/java/com/programmers/lime/global/config/security/AccessDeniedHandlerImpl.java b/lime-api/src/main/java/com/programmers/lime/global/config/security/handler/AccessDeniedHandlerImpl.java similarity index 92% rename from lime-api/src/main/java/com/programmers/lime/global/config/security/AccessDeniedHandlerImpl.java rename to lime-api/src/main/java/com/programmers/lime/global/config/security/handler/AccessDeniedHandlerImpl.java index f2296927b..c3e5b9900 100644 --- a/lime-api/src/main/java/com/programmers/lime/global/config/security/AccessDeniedHandlerImpl.java +++ b/lime-api/src/main/java/com/programmers/lime/global/config/security/handler/AccessDeniedHandlerImpl.java @@ -1,4 +1,4 @@ -package com.programmers.lime.global.config.security; +package com.programmers.lime.global.config.security.handler; import java.io.IOException; diff --git a/lime-api/src/main/java/com/programmers/lime/global/config/security/AuthenticationEntryPointImpl.java b/lime-api/src/main/java/com/programmers/lime/global/config/security/handler/AuthenticationEntryPointImpl.java similarity index 92% rename from lime-api/src/main/java/com/programmers/lime/global/config/security/AuthenticationEntryPointImpl.java rename to lime-api/src/main/java/com/programmers/lime/global/config/security/handler/AuthenticationEntryPointImpl.java index 478bf25a2..4b30cb3e9 100644 --- a/lime-api/src/main/java/com/programmers/lime/global/config/security/AuthenticationEntryPointImpl.java +++ b/lime-api/src/main/java/com/programmers/lime/global/config/security/handler/AuthenticationEntryPointImpl.java @@ -1,4 +1,4 @@ -package com.programmers.lime.global.config.security; +package com.programmers.lime.global.config.security.handler; import java.io.IOException; From 68683b6287a341c747a71a2fc8bb56a76f9b8716 Mon Sep 17 00:00:00 2001 From: JoJaeHyeon Date: Fri, 8 Mar 2024 13:52:13 +0900 Subject: [PATCH 11/16] =?UTF-8?q?refactor=20:=20=EC=9D=B8=EA=B0=80?= =?UTF-8?q?=EC=B2=98=EB=A6=AC=20=EB=8B=A8=EA=B3=84=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=EA=B6=8C=ED=95=9C=20=ED=99=95=EC=9D=B8=20=ED=9B=84=20=EC=9D=B8?= =?UTF-8?q?=EC=A6=9D=EC=B2=98=EB=A6=AC=20=EC=A0=84=20=ED=94=84=EB=A1=9C?= =?UTF-8?q?=ED=95=84=20=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8=20=EC=96=91?= =?UTF-8?q?=EC=8B=9D=EC=9C=BC=EB=A1=9C=20=EB=A6=AC=EB=8B=A4=EC=9D=B4?= =?UTF-8?q?=EB=A0=89=ED=8A=B8=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../global/config/security/SecurityConfiguration.java | 9 +++++++-- .../security/handler/AuthenticationEntryPointImpl.java | 7 +++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/lime-api/src/main/java/com/programmers/lime/global/config/security/SecurityConfiguration.java b/lime-api/src/main/java/com/programmers/lime/global/config/security/SecurityConfiguration.java index 38af0b7ea..67cd04460 100644 --- a/lime-api/src/main/java/com/programmers/lime/global/config/security/SecurityConfiguration.java +++ b/lime-api/src/main/java/com/programmers/lime/global/config/security/SecurityConfiguration.java @@ -11,6 +11,7 @@ import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.web.AuthenticationEntryPoint; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.access.AccessDeniedHandler; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; @@ -30,6 +31,7 @@ public class SecurityConfiguration { private final JwtAuthenticationFilter jwtAuthenticationFilter; private final AuthenticationProvider authenticationProvider; private final AccessDeniedHandler accessDeniedHandler; + private final AuthenticationEntryPoint authenticationEntryPoint; @Bean public SecurityFilterChain securityFilterChain(final HttpSecurity http) throws Exception { @@ -69,15 +71,18 @@ public SecurityFilterChain securityFilterChain(final HttpSecurity http) throws E .requestMatchers("/actuator/**").permitAll() .requestMatchers("/api/auth/kakao/callback").permitAll() + .requestMatchers("/join").authenticated() .anyRequest().hasRole("USER") - ) .sessionManagement(session -> session .sessionCreationPolicy(SessionCreationPolicy.STATELESS) ) .authenticationProvider(authenticationProvider) .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class) - .exceptionHandling((exceptions) -> exceptions.accessDeniedHandler(accessDeniedHandler)); + .exceptionHandling((exceptions) -> { + exceptions.accessDeniedHandler(accessDeniedHandler); + exceptions.authenticationEntryPoint(authenticationEntryPoint); + }); return http.build(); } diff --git a/lime-api/src/main/java/com/programmers/lime/global/config/security/handler/AuthenticationEntryPointImpl.java b/lime-api/src/main/java/com/programmers/lime/global/config/security/handler/AuthenticationEntryPointImpl.java index 4b30cb3e9..fab9c9bb1 100644 --- a/lime-api/src/main/java/com/programmers/lime/global/config/security/handler/AuthenticationEntryPointImpl.java +++ b/lime-api/src/main/java/com/programmers/lime/global/config/security/handler/AuthenticationEntryPointImpl.java @@ -13,8 +13,11 @@ @Component public class AuthenticationEntryPointImpl implements AuthenticationEntryPoint { @Override - public void commence(final HttpServletRequest request, final HttpServletResponse response, - final AuthenticationException authException) throws IOException, ServletException { + public void commence( + final HttpServletRequest request, + final HttpServletResponse response, + final AuthenticationException authException + ) throws IOException, ServletException { response.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY); response.sendRedirect("/join"); } From f2332eb33e79d457f5cdf0a5105470ff51cea3d2 Mon Sep 17 00:00:00 2001 From: JoJaeHyeon Date: Fri, 8 Mar 2024 15:24:41 +0900 Subject: [PATCH 12/16] =?UTF-8?q?chore=20:=20=EC=82=AC=EC=9A=A9=ED=95=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EB=8A=94=20=EC=BD=94=EB=93=9C=20=EC=A0=95?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../handler/AuthenticationEntryPointImpl.java | 24 ------------------- .../security/jwt/JwtAuthenticationFilter.java | 22 ----------------- 2 files changed, 46 deletions(-) delete mode 100644 lime-api/src/main/java/com/programmers/lime/global/config/security/handler/AuthenticationEntryPointImpl.java diff --git a/lime-api/src/main/java/com/programmers/lime/global/config/security/handler/AuthenticationEntryPointImpl.java b/lime-api/src/main/java/com/programmers/lime/global/config/security/handler/AuthenticationEntryPointImpl.java deleted file mode 100644 index fab9c9bb1..000000000 --- a/lime-api/src/main/java/com/programmers/lime/global/config/security/handler/AuthenticationEntryPointImpl.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.programmers.lime.global.config.security.handler; - -import java.io.IOException; - -import org.springframework.security.core.AuthenticationException; -import org.springframework.security.web.AuthenticationEntryPoint; -import org.springframework.stereotype.Component; - -import jakarta.servlet.ServletException; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; - -@Component -public class AuthenticationEntryPointImpl implements AuthenticationEntryPoint { - @Override - public void commence( - final HttpServletRequest request, - final HttpServletResponse response, - final AuthenticationException authException - ) throws IOException, ServletException { - response.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY); - response.sendRedirect("/join"); - } -} diff --git a/lime-api/src/main/java/com/programmers/lime/global/config/security/jwt/JwtAuthenticationFilter.java b/lime-api/src/main/java/com/programmers/lime/global/config/security/jwt/JwtAuthenticationFilter.java index 6204a3122..d3cc6bdd8 100644 --- a/lime-api/src/main/java/com/programmers/lime/global/config/security/jwt/JwtAuthenticationFilter.java +++ b/lime-api/src/main/java/com/programmers/lime/global/config/security/jwt/JwtAuthenticationFilter.java @@ -62,13 +62,6 @@ protected void doFilterInternal( final String memberId = jwtService.extractUsername(jwt); final UserDetails principal = makePrincipal(memberId); - // if(needsProfileUpdate(principal)){ - // // response.setHeader("Location","http://localhost:8080/join"); - // // response.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY); - // // response.sendRedirect("http://localhost:8080/join"); - // - // } - final UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken( principal, null, @@ -85,22 +78,7 @@ protected void doFilterInternal( } } - // private static boolean needsProfileUpdate(final UserDetails principal) { - // Collection authorities = principal.getAuthorities(); - // for(GrantedAuthority authority : authorities){ - // String role = authority.getAuthority(); - // if(role.equals("ROLE_GUEST")){ - // return true; - // } - // } - // return false; - // } - private UserDetails makePrincipal(final String memberId) { return userDetailsService.loadUserByUsername(memberId); } - - // private static UserDetails makePrincipal(final String memberId) { - // return new User(memberId, "", List.of(new SimpleGrantedAuthority("ROLE_USER"))); - // } } From 188a92a1bc6ca33669ab91620c772f4b2974e105 Mon Sep 17 00:00:00 2001 From: JoJaeHyeon Date: Fri, 8 Mar 2024 15:25:39 +0900 Subject: [PATCH 13/16] =?UTF-8?q?refactor=20:=20join=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=EB=A1=9C=20=EB=A6=AC=EB=8B=A4=EC=9D=B4=EB=A0=89?= =?UTF-8?q?=ED=8A=B8,=20=ED=95=B4=EB=8B=B9=20=EA=B6=8C=ED=95=9C=20?= =?UTF-8?q?=EC=8A=B9=EC=9D=B8=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lime/domains/auth/api/AuthController.java | 9 +++++---- .../global/config/security/SecurityConfiguration.java | 10 +++------- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/lime-api/src/main/java/com/programmers/lime/domains/auth/api/AuthController.java b/lime-api/src/main/java/com/programmers/lime/domains/auth/api/AuthController.java index dfcf2727c..7576a6466 100644 --- a/lime-api/src/main/java/com/programmers/lime/domains/auth/api/AuthController.java +++ b/lime-api/src/main/java/com/programmers/lime/domains/auth/api/AuthController.java @@ -2,18 +2,14 @@ import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import com.programmers.lime.domains.auth.application.OAuthUserService; import com.programmers.lime.domains.member.api.dto.response.MemberLoginResponse; import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -@Slf4j @RequiredArgsConstructor -@RequestMapping("/api") @RestController public class AuthController { @@ -25,4 +21,9 @@ public ResponseEntity loginKakao( ) { return ResponseEntity.ok(oauthUserService.login(code)); } + + @GetMapping("/join") + public ResponseEntity join(){ + return ResponseEntity.ok("join"); + } } diff --git a/lime-api/src/main/java/com/programmers/lime/global/config/security/SecurityConfiguration.java b/lime-api/src/main/java/com/programmers/lime/global/config/security/SecurityConfiguration.java index 67cd04460..e4d26dcd7 100644 --- a/lime-api/src/main/java/com/programmers/lime/global/config/security/SecurityConfiguration.java +++ b/lime-api/src/main/java/com/programmers/lime/global/config/security/SecurityConfiguration.java @@ -11,7 +11,6 @@ import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; import org.springframework.security.config.http.SessionCreationPolicy; -import org.springframework.security.web.AuthenticationEntryPoint; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.access.AccessDeniedHandler; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; @@ -31,7 +30,6 @@ public class SecurityConfiguration { private final JwtAuthenticationFilter jwtAuthenticationFilter; private final AuthenticationProvider authenticationProvider; private final AccessDeniedHandler accessDeniedHandler; - private final AuthenticationEntryPoint authenticationEntryPoint; @Bean public SecurityFilterChain securityFilterChain(final HttpSecurity http) throws Exception { @@ -71,7 +69,7 @@ public SecurityFilterChain securityFilterChain(final HttpSecurity http) throws E .requestMatchers("/actuator/**").permitAll() .requestMatchers("/api/auth/kakao/callback").permitAll() - .requestMatchers("/join").authenticated() + .requestMatchers("/join").permitAll() .anyRequest().hasRole("USER") ) .sessionManagement(session -> session @@ -79,10 +77,8 @@ public SecurityFilterChain securityFilterChain(final HttpSecurity http) throws E ) .authenticationProvider(authenticationProvider) .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class) - .exceptionHandling((exceptions) -> { - exceptions.accessDeniedHandler(accessDeniedHandler); - exceptions.authenticationEntryPoint(authenticationEntryPoint); - }); + .exceptionHandling((exceptions) -> exceptions.accessDeniedHandler(accessDeniedHandler) + ); return http.build(); } From 05d9cf064aae278e68608bc4c3937e4fb3ea6426 Mon Sep 17 00:00:00 2001 From: JoJaeHyeon Date: Sat, 9 Mar 2024 15:02:33 +0900 Subject: [PATCH 14/16] =?UTF-8?q?refactor=20:=20refreshToken=EC=A0=84?= =?UTF-8?q?=EB=8B=AC=EB=B0=A9=EC=8B=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lime/domains/auth/api/AuthController.java | 29 +++++++++++++++++-- .../api/dto/response/MemberLoginResponse.java | 3 ++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/lime-api/src/main/java/com/programmers/lime/domains/auth/api/AuthController.java b/lime-api/src/main/java/com/programmers/lime/domains/auth/api/AuthController.java index 7576a6466..0c3302993 100644 --- a/lime-api/src/main/java/com/programmers/lime/domains/auth/api/AuthController.java +++ b/lime-api/src/main/java/com/programmers/lime/domains/auth/api/AuthController.java @@ -1,5 +1,9 @@ package com.programmers.lime.domains.auth.api; +import static com.programmers.lime.domains.member.api.MemberController.*; +import static org.springframework.http.HttpHeaders.*; + +import org.springframework.http.ResponseCookie; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; @@ -7,6 +11,8 @@ import com.programmers.lime.domains.auth.application.OAuthUserService; import com.programmers.lime.domains.member.api.dto.response.MemberLoginResponse; + +import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; @RequiredArgsConstructor @@ -17,13 +23,32 @@ public class AuthController { @GetMapping("/auth/kakao/callback") public ResponseEntity loginKakao( - @RequestParam final String code + @RequestParam final String code, + HttpServletResponse response ) { - return ResponseEntity.ok(oauthUserService.login(code)); + MemberLoginResponse loginResponse = oauthUserService.login(code); + sendRefreshToken(response, loginResponse); + + return ResponseEntity.ok(loginResponse); } @GetMapping("/join") public ResponseEntity join(){ return ResponseEntity.ok("join"); } + + private void sendRefreshToken( + final HttpServletResponse response, + final MemberLoginResponse loginResponse + ) { + final ResponseCookie cookie = ResponseCookie.from("refresh-token", loginResponse.refreshToken()) + .maxAge(COOKIE_AGE_SECONDS) + .secure(true) + .httpOnly(true) + .sameSite("None") + .path("/") + .build(); + + response.addHeader(SET_COOKIE, String.valueOf(cookie)); + } } diff --git a/lime-api/src/main/java/com/programmers/lime/domains/member/api/dto/response/MemberLoginResponse.java b/lime-api/src/main/java/com/programmers/lime/domains/member/api/dto/response/MemberLoginResponse.java index e58a59106..e6b02bee3 100644 --- a/lime-api/src/main/java/com/programmers/lime/domains/member/api/dto/response/MemberLoginResponse.java +++ b/lime-api/src/main/java/com/programmers/lime/domains/member/api/dto/response/MemberLoginResponse.java @@ -1,11 +1,14 @@ package com.programmers.lime.domains.member.api.dto.response; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.programmers.lime.domains.member.domain.Member; public record MemberLoginResponse( Long memberId, String nickname, String accessToken, + + @JsonIgnore String refreshToken ) { public static MemberLoginResponse from( From 2f942806e5339a5371a649af680101a483dc8072 Mon Sep 17 00:00:00 2001 From: JoJaeHyeon Date: Sat, 9 Mar 2024 15:02:48 +0900 Subject: [PATCH 15/16] =?UTF-8?q?chore=20:=20=EC=BB=A8=EB=B2=A4=EC=85=98?= =?UTF-8?q?=20=EB=B0=8F=20=EC=82=AC=EC=9A=A9=20=EB=AC=B8=EB=B2=95=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lime/domains/auth/application/OAuthUserService.java | 2 +- .../programmers/lime/global/config/security/MemberSecurity.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lime-api/src/main/java/com/programmers/lime/domains/auth/application/OAuthUserService.java b/lime-api/src/main/java/com/programmers/lime/domains/auth/application/OAuthUserService.java index 2dc8c4476..26d08316d 100644 --- a/lime-api/src/main/java/com/programmers/lime/domains/auth/application/OAuthUserService.java +++ b/lime-api/src/main/java/com/programmers/lime/domains/auth/application/OAuthUserService.java @@ -23,7 +23,7 @@ public class OAuthUserService { private final JwtService jwtService; @Transactional - public MemberLoginResponse login(String code) { + public MemberLoginResponse login(final String code) { String kakaoAccessToken = kakaoOAuthClient.getAccessToken(code); KakaoMemberResponse response = kakaoOAuthClient.getMemberInfo(kakaoAccessToken); diff --git a/lime-api/src/main/java/com/programmers/lime/global/config/security/MemberSecurity.java b/lime-api/src/main/java/com/programmers/lime/global/config/security/MemberSecurity.java index 988312943..3d4d3330d 100644 --- a/lime-api/src/main/java/com/programmers/lime/global/config/security/MemberSecurity.java +++ b/lime-api/src/main/java/com/programmers/lime/global/config/security/MemberSecurity.java @@ -19,7 +19,7 @@ public class MemberSecurity implements UserDetails { @Override public Collection getAuthorities() { - return List.of(new SimpleGrantedAuthority("ROLE_" + member.getRole().name())); + return List.of(new SimpleGrantedAuthority(member.getRole().getKey())); } @Override From 852f50ec642c5279de54240168e007053ef72abc Mon Sep 17 00:00:00 2001 From: JoJaeHyeon Date: Sat, 9 Mar 2024 15:37:30 +0900 Subject: [PATCH 16/16] =?UTF-8?q?refactor=20:=20=EB=A0=88=EC=9D=B4?= =?UTF-8?q?=EC=96=B4=20=EC=97=AD=EC=B0=B8=EC=A1=B0=20=EB=AC=B8=EC=A0=9C=20?= =?UTF-8?q?=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lime/domains/auth/api/AuthController.java | 11 ++++++----- .../domains/auth/api/dto/MemberLoginResponse.java | 13 +++++++++++++ .../domains/auth/application/OAuthUserService.java | 6 +++--- .../dto/MemberLoginServiceResponse.java} | 11 ++++------- 4 files changed, 26 insertions(+), 15 deletions(-) create mode 100644 lime-api/src/main/java/com/programmers/lime/domains/auth/api/dto/MemberLoginResponse.java rename lime-api/src/main/java/com/programmers/lime/domains/{member/api/dto/response/MemberLoginResponse.java => auth/application/dto/MemberLoginServiceResponse.java} (57%) diff --git a/lime-api/src/main/java/com/programmers/lime/domains/auth/api/AuthController.java b/lime-api/src/main/java/com/programmers/lime/domains/auth/api/AuthController.java index 0c3302993..1739b587c 100644 --- a/lime-api/src/main/java/com/programmers/lime/domains/auth/api/AuthController.java +++ b/lime-api/src/main/java/com/programmers/lime/domains/auth/api/AuthController.java @@ -9,8 +9,9 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +import com.programmers.lime.domains.auth.api.dto.MemberLoginResponse; import com.programmers.lime.domains.auth.application.OAuthUserService; -import com.programmers.lime.domains.member.api.dto.response.MemberLoginResponse; +import com.programmers.lime.domains.auth.application.dto.MemberLoginServiceResponse; import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; @@ -26,10 +27,10 @@ public ResponseEntity loginKakao( @RequestParam final String code, HttpServletResponse response ) { - MemberLoginResponse loginResponse = oauthUserService.login(code); - sendRefreshToken(response, loginResponse); + MemberLoginServiceResponse loginServiceResponse = oauthUserService.login(code); + sendRefreshToken(response, loginServiceResponse); - return ResponseEntity.ok(loginResponse); + return ResponseEntity.ok(MemberLoginResponse.from(loginServiceResponse)); } @GetMapping("/join") @@ -39,7 +40,7 @@ public ResponseEntity join(){ private void sendRefreshToken( final HttpServletResponse response, - final MemberLoginResponse loginResponse + final MemberLoginServiceResponse loginResponse ) { final ResponseCookie cookie = ResponseCookie.from("refresh-token", loginResponse.refreshToken()) .maxAge(COOKIE_AGE_SECONDS) diff --git a/lime-api/src/main/java/com/programmers/lime/domains/auth/api/dto/MemberLoginResponse.java b/lime-api/src/main/java/com/programmers/lime/domains/auth/api/dto/MemberLoginResponse.java new file mode 100644 index 000000000..e9ec1d8ab --- /dev/null +++ b/lime-api/src/main/java/com/programmers/lime/domains/auth/api/dto/MemberLoginResponse.java @@ -0,0 +1,13 @@ +package com.programmers.lime.domains.auth.api.dto; + +import com.programmers.lime.domains.auth.application.dto.MemberLoginServiceResponse; + +public record MemberLoginResponse( + Long memberId, + String nickname, + String accessToken +) { + public static MemberLoginResponse from(final MemberLoginServiceResponse response) { + return new MemberLoginResponse(response.memberId(), response.nickname(), response.accessToken()); + } +} diff --git a/lime-api/src/main/java/com/programmers/lime/domains/auth/application/OAuthUserService.java b/lime-api/src/main/java/com/programmers/lime/domains/auth/application/OAuthUserService.java index 26d08316d..170e44a82 100644 --- a/lime-api/src/main/java/com/programmers/lime/domains/auth/application/OAuthUserService.java +++ b/lime-api/src/main/java/com/programmers/lime/domains/auth/application/OAuthUserService.java @@ -4,7 +4,7 @@ import org.springframework.transaction.annotation.Transactional; import com.programmers.lime.domains.auth.api.dto.KakaoMemberResponse; -import com.programmers.lime.domains.member.api.dto.response.MemberLoginResponse; +import com.programmers.lime.domains.auth.application.dto.MemberLoginServiceResponse; import com.programmers.lime.domains.member.domain.Member; import com.programmers.lime.domains.member.domain.vo.SocialType; import com.programmers.lime.domains.member.implementation.MemberAppender; @@ -23,7 +23,7 @@ public class OAuthUserService { private final JwtService jwtService; @Transactional - public MemberLoginResponse login(final String code) { + public MemberLoginServiceResponse login(final String code) { String kakaoAccessToken = kakaoOAuthClient.getAccessToken(code); KakaoMemberResponse response = kakaoOAuthClient.getMemberInfo(kakaoAccessToken); @@ -35,7 +35,7 @@ public MemberLoginResponse login(final String code) { String accessToken = jwtService.generateAccessToken(String.valueOf(foundMember.getId())); String refreshToken = jwtService.generateRefreshToken(); - return MemberLoginResponse.from(foundMember, accessToken, refreshToken); + return MemberLoginServiceResponse.from(foundMember, accessToken, refreshToken); } private Member saveMember(final KakaoMemberResponse response) { diff --git a/lime-api/src/main/java/com/programmers/lime/domains/member/api/dto/response/MemberLoginResponse.java b/lime-api/src/main/java/com/programmers/lime/domains/auth/application/dto/MemberLoginServiceResponse.java similarity index 57% rename from lime-api/src/main/java/com/programmers/lime/domains/member/api/dto/response/MemberLoginResponse.java rename to lime-api/src/main/java/com/programmers/lime/domains/auth/application/dto/MemberLoginServiceResponse.java index e6b02bee3..cd3a4eae6 100644 --- a/lime-api/src/main/java/com/programmers/lime/domains/member/api/dto/response/MemberLoginResponse.java +++ b/lime-api/src/main/java/com/programmers/lime/domains/auth/application/dto/MemberLoginServiceResponse.java @@ -1,22 +1,19 @@ -package com.programmers.lime.domains.member.api.dto.response; +package com.programmers.lime.domains.auth.application.dto; -import com.fasterxml.jackson.annotation.JsonIgnore; import com.programmers.lime.domains.member.domain.Member; -public record MemberLoginResponse( +public record MemberLoginServiceResponse( Long memberId, String nickname, String accessToken, - - @JsonIgnore String refreshToken ) { - public static MemberLoginResponse from( + public static MemberLoginServiceResponse from( final Member member, final String accessToken, final String refreshToken ) { - return new MemberLoginResponse( + return new MemberLoginServiceResponse( member.getId(), member.getNickname(), accessToken,