From 28ec6b177663fb6544c8a9db09fa193b66793c84 Mon Sep 17 00:00:00 2001 From: born-A Date: Tue, 31 Oct 2023 18:48:37 +0900 Subject: [PATCH] =?UTF-8?q?NABI-102-refsctor=20:=20=EC=B9=B4=EC=B9=B4?= =?UTF-8?q?=EC=98=A4=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=EC=95=84=ED=82=A4?= =?UTF-8?q?=ED=85=8D=EC=B3=90=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 7 +- .../nabimarketbe/NabiMarketBeApplication.java | 4 +- .../nabimarketbe/config/SecurityConfig.java | 67 ----------------- .../{controller => api}/UserController.java | 22 +++--- .../user/controller/SignController.java | 72 ------------------- .../nabimarketbe/domain/user/entity/User.java | 8 ++- .../domain/user/repository/UserJpaRepo.java | 1 + .../domain/user/service/SignService.java | 60 +++++++++++----- .../{domain/user => global}/BaseEntity.java | 2 +- .../config}/SecurityConfiguration.java | 13 ++-- .../security/entity/RefreshToken.java | 6 +- .../handler}/CustomAccessDeniedHandler.java | 2 +- .../CustomAuthenticationEntryPoint.java | 2 +- .../security/jwt/dto/TokenRequestDto.java | 20 ++++++ .../jwt/filter}/JwtAuthenticationFilter.java | 3 +- .../security/jwt/provider}/JwtProvider.java | 8 +-- .../ResponseFactory.java} | 12 ++-- .../{ => util}/model/CommonResponse.java | 2 +- .../global/{ => util}/model/CommonResult.java | 2 +- .../global/{ => util}/model/ListResult.java | 2 +- .../global/{ => util}/model/SingleResult.java | 2 +- .../member/domain/LoginResponseDTO.java | 9 --- .../member/domain/GoogleOAuth2Token.java | 4 +- .../google}/member/domain/GoogleUser.java | 2 +- .../member/domain/LoginResponseDTO.java | 9 +++ .../google}/member/domain/OAuth2.java | 2 +- .../google}/member/domain/Role.java | 2 +- .../google}/member/dto/OAuth2Attributes.java | 19 +++-- .../member/oauth2/CustomOAuth2User.java | 4 +- .../service/CustomOAuth2UserService.java | 12 ++-- .../kakao/api/OAuth2Controller.java} | 56 +++++++++------ .../kakao/dto}/KakaoProfile.java | 2 +- .../kakao/dto}/RetKakaoOAuth.java | 2 +- .../repository/RefreshTokenJpaRepo.java | 4 +- .../service/CustomUserDetailsService.java | 2 +- .../kakao/service/OAuth2Service.java} | 8 +-- ...lerTest.java => OAuth2ControllerTest.java} | 13 ++-- .../user/controller/UserControllerTest.java | 9 +-- ...erviceTest.java => OAuth2ServiceTest.java} | 19 +++-- 39 files changed, 209 insertions(+), 286 deletions(-) delete mode 100644 src/main/java/org/prgrms/nabimarketbe/config/SecurityConfig.java rename src/main/java/org/prgrms/nabimarketbe/domain/user/{controller => api}/UserController.java (66%) delete mode 100644 src/main/java/org/prgrms/nabimarketbe/domain/user/controller/SignController.java rename src/main/java/org/prgrms/nabimarketbe/{domain/user => global}/BaseEntity.java (94%) rename src/main/java/org/prgrms/nabimarketbe/{domain/security => global/config}/SecurityConfiguration.java (78%) rename src/main/java/org/prgrms/nabimarketbe/{domain => global}/security/entity/RefreshToken.java (81%) rename src/main/java/org/prgrms/nabimarketbe/{domain/security => global/security/handler}/CustomAccessDeniedHandler.java (92%) rename src/main/java/org/prgrms/nabimarketbe/{domain/security => global/security/handler}/CustomAuthenticationEntryPoint.java (92%) create mode 100644 src/main/java/org/prgrms/nabimarketbe/global/security/jwt/dto/TokenRequestDto.java rename src/main/java/org/prgrms/nabimarketbe/{domain/security/jwt => global/security/jwt/filter}/JwtAuthenticationFilter.java (92%) rename src/main/java/org/prgrms/nabimarketbe/{domain/security/jwt => global/security/jwt/provider}/JwtProvider.java (94%) rename src/main/java/org/prgrms/nabimarketbe/global/{ResponseService.java => util/ResponseFactory.java} (82%) rename src/main/java/org/prgrms/nabimarketbe/global/{ => util}/model/CommonResponse.java (82%) rename src/main/java/org/prgrms/nabimarketbe/global/{ => util}/model/CommonResult.java (76%) rename src/main/java/org/prgrms/nabimarketbe/global/{ => util}/model/ListResult.java (76%) rename src/main/java/org/prgrms/nabimarketbe/global/{ => util}/model/SingleResult.java (72%) delete mode 100644 src/main/java/org/prgrms/nabimarketbe/member/domain/LoginResponseDTO.java rename src/main/java/org/prgrms/nabimarketbe/{ => oauth2/google}/member/domain/GoogleOAuth2Token.java (70%) rename src/main/java/org/prgrms/nabimarketbe/{ => oauth2/google}/member/domain/GoogleUser.java (73%) create mode 100644 src/main/java/org/prgrms/nabimarketbe/oauth2/google/member/domain/LoginResponseDTO.java rename src/main/java/org/prgrms/nabimarketbe/{ => oauth2/google}/member/domain/OAuth2.java (89%) rename src/main/java/org/prgrms/nabimarketbe/{ => oauth2/google}/member/domain/Role.java (75%) rename src/main/java/org/prgrms/nabimarketbe/{ => oauth2/google}/member/dto/OAuth2Attributes.java (75%) rename src/main/java/org/prgrms/nabimarketbe/{ => oauth2/google}/member/oauth2/CustomOAuth2User.java (88%) rename src/main/java/org/prgrms/nabimarketbe/{ => oauth2/google}/member/oauth2/service/CustomOAuth2UserService.java (84%) rename src/main/java/org/prgrms/nabimarketbe/{domain/security/oauth/controller/KOAuthController.java => oauth2/kakao/api/OAuth2Controller.java} (55%) rename src/main/java/org/prgrms/nabimarketbe/{domain/security/oauth/dto/social => oauth2/kakao/dto}/KakaoProfile.java (78%) rename src/main/java/org/prgrms/nabimarketbe/{domain/security/oauth/dto/social => oauth2/kakao/dto}/RetKakaoOAuth.java (80%) rename src/main/java/org/prgrms/nabimarketbe/{domain/security => oauth2/kakao}/repository/RefreshTokenJpaRepo.java (64%) rename src/main/java/org/prgrms/nabimarketbe/{domain/security => oauth2/kakao}/service/CustomUserDetailsService.java (93%) rename src/main/java/org/prgrms/nabimarketbe/{domain/security/service/KakaoService.java => oauth2/kakao/service/OAuth2Service.java} (92%) rename src/test/java/org/prgrms/nabimarketbe/oauth/controller/{KOAuthControllerTest.java => OAuth2ControllerTest.java} (84%) rename src/test/java/org/prgrms/nabimarketbe/user/service/{KakaoServiceTest.java => OAuth2ServiceTest.java} (64%) diff --git a/build.gradle b/build.gradle index 8d7dc503..d1cdb59e 100644 --- a/build.gradle +++ b/build.gradle @@ -33,8 +33,10 @@ dependencies { runtimeOnly 'com.h2database:h2' runtimeOnly 'com.mysql:mysql-connector-j' annotationProcessor 'org.projectlombok:lombok' - testImplementation 'org.springframework.boot:spring-boot-starter-test' + testImplementation 'org.springframework.security:spring-security-test' + testImplementation 'org.springframework.boot:spring-boot-starter-test' + // Json을 결과로 매핑하기 위한 의존성 implementation 'com.google.code.gson:gson:2.8.8' @@ -42,6 +44,9 @@ dependencies { // 다국어 제공을 위한 i18n을 yml 파일로 적용하기 위한 의존성 implementation 'net.rakugakibox.util:yaml-resource-bundle:1.1' + + // jwt 의존성 - JWT의 생성 및 유효성 검사와 관련된 기본적인 기능 + implementation 'io.jsonwebtoken:jjwt:0.9.1' } tasks.named('test') { diff --git a/src/main/java/org/prgrms/nabimarketbe/NabiMarketBeApplication.java b/src/main/java/org/prgrms/nabimarketbe/NabiMarketBeApplication.java index 39ebb2cd..4d65a3bc 100644 --- a/src/main/java/org/prgrms/nabimarketbe/NabiMarketBeApplication.java +++ b/src/main/java/org/prgrms/nabimarketbe/NabiMarketBeApplication.java @@ -14,9 +14,9 @@ public static void main(String[] args) { SpringApplication.run(NabiMarketBeApplication.class, args); } + @Bean - public RestTemplate getRestTemplate() { + public RestTemplate restTemplate() { return new RestTemplate(); } - } diff --git a/src/main/java/org/prgrms/nabimarketbe/config/SecurityConfig.java b/src/main/java/org/prgrms/nabimarketbe/config/SecurityConfig.java deleted file mode 100644 index 834ad7cf..00000000 --- a/src/main/java/org/prgrms/nabimarketbe/config/SecurityConfig.java +++ /dev/null @@ -1,67 +0,0 @@ -package org.prgrms.nabimarketbe.config; - -import org.prgrms.nabimarketbe.member.oauth2.handler.OAuth2LoginSuccessHandler; -import org.prgrms.nabimarketbe.member.oauth2.service.CustomOAuth2UserService; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.config.http.SessionCreationPolicy; -import org.springframework.security.crypto.factory.PasswordEncoderFactories; -import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.security.web.SecurityFilterChain; - -import lombok.RequiredArgsConstructor; - -@Configuration -@RequiredArgsConstructor -@EnableWebSecurity -public class SecurityConfig { - - private final OAuth2LoginSuccessHandler oAuth2LoginSuccessHandler; - - private final CustomOAuth2UserService customOAuth2UserService; - - @Bean - public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { - http - .formLogin().disable() // FormLogin 사용 X - .httpBasic().disable() // httpBasic 사용 X - .csrf().disable() // csrf 보안 사용 X - .headers().frameOptions().disable() - .and() - // 세션 사용하지 않으므로 STATELESS로 설정 - .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) - .and() - //== URL별 권한 관리 옵션 ==// - .authorizeRequests() - - // 아이콘, css, js 관련 - // 기본 페이지, css, image, js 하위 폴더에 있는 자료들은 모두 접근 가능, h2-console에 접근 가능 - .antMatchers("/","/css/**","/images/**","/js/**","/favicon.ico","/h2-console/**").permitAll() - .antMatchers("/sign-up").permitAll() // 회원가입 접근 가능 - .antMatchers("/test").authenticated() // 토큰 인증된 사용자 용 - .anyRequest().permitAll() - .and() - //== 소셜 로그인 설정 ==// - .oauth2Login() - .loginPage("/api/v1/users/oauth2/authorize/google/login") - .permitAll() - .defaultSuccessUrl("/home", true) - .successHandler(oAuth2LoginSuccessHandler) - .userInfoEndpoint() - .userService(customOAuth2UserService); // customUserService 설정 - - // 원래 스프링 시큐리티 필터 순서가 LogoutFilter 이후에 로그인 필터 동작 - // 따라서, LogoutFilter 이후에 우리가 만든 필터 동작하도록 설정 - // 순서 : LogoutFilter -> JwtAuthenticationProcessingFilter -> CustomJsonUsernamePasswordAuthenticationFilter - - return http.build(); - } - - @Bean - public PasswordEncoder passwordEncoder() { - return PasswordEncoderFactories.createDelegatingPasswordEncoder(); - } - -} diff --git a/src/main/java/org/prgrms/nabimarketbe/domain/user/controller/UserController.java b/src/main/java/org/prgrms/nabimarketbe/domain/user/api/UserController.java similarity index 66% rename from src/main/java/org/prgrms/nabimarketbe/domain/user/controller/UserController.java rename to src/main/java/org/prgrms/nabimarketbe/domain/user/api/UserController.java index 98e24eb9..ecc6509d 100644 --- a/src/main/java/org/prgrms/nabimarketbe/domain/user/controller/UserController.java +++ b/src/main/java/org/prgrms/nabimarketbe/domain/user/api/UserController.java @@ -1,14 +1,14 @@ -package org.prgrms.nabimarketbe.domain.user.controller; +package org.prgrms.nabimarketbe.domain.user.api; import lombok.RequiredArgsConstructor; import org.prgrms.nabimarketbe.domain.user.dto.UserRequestDto; import org.prgrms.nabimarketbe.domain.user.dto.UserResponseDto; import org.prgrms.nabimarketbe.domain.user.service.UserService; -import org.prgrms.nabimarketbe.global.model.CommonResult; -import org.prgrms.nabimarketbe.global.model.ListResult; -import org.prgrms.nabimarketbe.global.model.SingleResult; -import org.prgrms.nabimarketbe.global.ResponseService; +import org.prgrms.nabimarketbe.global.util.model.CommonResult; +import org.prgrms.nabimarketbe.global.util.model.ListResult; +import org.prgrms.nabimarketbe.global.util.model.SingleResult; +import org.prgrms.nabimarketbe.global.util.ResponseFactory; import org.springframework.web.bind.annotation.*; @@ -18,21 +18,21 @@ public class UserController { private final UserService userService; - private final ResponseService responseService; + private final ResponseFactory responseFactory; @GetMapping("/user/id/{userId}") public SingleResult findUserById(@PathVariable Long userId) { - return responseService.getSingleResult(userService.findById(userId)); + return responseFactory.getSingleResult(userService.findById(userId)); } @GetMapping("/user/nickname/{nickname}") public SingleResult findUserByNickName(@PathVariable String nickname) { - return responseService.getSingleResult(userService.findByNickName(nickname)); + return responseFactory.getSingleResult(userService.findByNickName(nickname)); } @GetMapping("/users") public ListResult findAllUser() { - return responseService.getListResult(userService.findAllUser()); + return responseFactory.getListResult(userService.findAllUser()); } @PutMapping("/user") @@ -44,13 +44,13 @@ public SingleResult update ( .nickName(nickname) .build(); - return responseService.getSingleResult(userService.update(userId, userRequestDto)); + return responseFactory.getSingleResult(userService.update(userId, userRequestDto)); } @DeleteMapping("/user/{userId}") public CommonResult delete(@PathVariable Long userId) { userService.delete(userId); - return responseService.getSuccessResult(); + return responseFactory.getSuccessResult(); } } diff --git a/src/main/java/org/prgrms/nabimarketbe/domain/user/controller/SignController.java b/src/main/java/org/prgrms/nabimarketbe/domain/user/controller/SignController.java deleted file mode 100644 index aea4ed94..00000000 --- a/src/main/java/org/prgrms/nabimarketbe/domain/user/controller/SignController.java +++ /dev/null @@ -1,72 +0,0 @@ -package org.prgrms.nabimarketbe.domain.user.controller; - -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; - -import org.prgrms.nabimarketbe.domain.security.jwt.dto.TokenRequestDto; -import org.prgrms.nabimarketbe.domain.user.dto.sign.UserSignupRequestDto; -import org.prgrms.nabimarketbe.domain.user.dto.sign.UserSocialLoginRequestDto; -import org.prgrms.nabimarketbe.domain.user.dto.sign.UserSocialSignupRequestDto; -import org.prgrms.nabimarketbe.domain.user.service.SignService; -import org.prgrms.nabimarketbe.domain.security.jwt.JwtProvider; -import org.prgrms.nabimarketbe.domain.security.jwt.dto.TokenResponseDto; -import org.prgrms.nabimarketbe.domain.security.oauth.dto.social.KakaoProfile; -import org.prgrms.nabimarketbe.global.model.CommonResult; -import org.prgrms.nabimarketbe.global.model.SingleResult; -import org.prgrms.nabimarketbe.global.ResponseService; -import org.prgrms.nabimarketbe.domain.user.entity.User; -import org.prgrms.nabimarketbe.domain.user.repository.UserJpaRepo; -import org.prgrms.nabimarketbe.domain.security.service.KakaoService; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -@Slf4j -@RequiredArgsConstructor -@RestController -@RequestMapping("/v1") -public class SignController { - private final JwtProvider jwtProvider; - - private final UserJpaRepo userJpaRepo; - - private final KakaoService kakaoService; - - private final SignService signService; - - private final ResponseService responseService; - - @PostMapping("/social/login/kakao") - public SingleResult loginByKakao(@RequestBody UserSocialLoginRequestDto socialLoginRequestDto) { - KakaoProfile kakaoProfile = kakaoService.getKakaoProfile(socialLoginRequestDto.accessToken()); - - if (kakaoProfile == null) throw new RuntimeException("해당 회원이 없습니다."); - - User user = userJpaRepo.findByNicknameAndProvider(kakaoProfile.getProperties().getNickname(), "kakao") - .orElseThrow(() -> new RuntimeException("해당 회원이 없습니다.")); - - return responseService.getSingleResult(jwtProvider.createTokenDto(user.getUserId(), user.getRoles())); - } - - @PostMapping("/social/signup/kakao") - public CommonResult signupBySocial(@RequestBody UserSocialSignupRequestDto socialSignupRequestDto) { - KakaoProfile kakaoProfile = kakaoService.getKakaoProfile(socialSignupRequestDto.accessToken()); - - if (kakaoProfile == null) throw new RuntimeException("해당 회원이 없습니다."); - - Long userId = signService.socialSignup(UserSignupRequestDto.builder() - .nickname(kakaoProfile.getProperties().getNickname()) - .provider("kakao") - .build()); - - return responseService.getSingleResult(userId); - } - - //엑세스 토큰 만료시 회원 검증 후 리프레쉬 토큰을 검증해서 액세스 토큰과 리프레시 토큰을 재발급 - @PostMapping("/reissue") - public SingleResult reissue( - @RequestBody TokenRequestDto tokenRequestDto) { - return responseService.getSingleResult(signService.reissue(tokenRequestDto)); - } -} diff --git a/src/main/java/org/prgrms/nabimarketbe/domain/user/entity/User.java b/src/main/java/org/prgrms/nabimarketbe/domain/user/entity/User.java index 2f76f99d..22fb817d 100644 --- a/src/main/java/org/prgrms/nabimarketbe/domain/user/entity/User.java +++ b/src/main/java/org/prgrms/nabimarketbe/domain/user/entity/User.java @@ -5,7 +5,7 @@ import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; -import org.prgrms.nabimarketbe.domain.user.BaseEntity; +import org.prgrms.nabimarketbe.global.BaseEntity; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.UserDetails; @@ -30,6 +30,12 @@ public class User extends BaseEntity implements UserDetails { @Column(name = "nick_name", nullable = false, length = 20) private String nickname; + @Column(name = "user_email") + private String email; + + @Column(name = "user_image_url") + private String image_url; + @Column(length = 100) private String provider; diff --git a/src/main/java/org/prgrms/nabimarketbe/domain/user/repository/UserJpaRepo.java b/src/main/java/org/prgrms/nabimarketbe/domain/user/repository/UserJpaRepo.java index 3d00009e..5db57dd2 100644 --- a/src/main/java/org/prgrms/nabimarketbe/domain/user/repository/UserJpaRepo.java +++ b/src/main/java/org/prgrms/nabimarketbe/domain/user/repository/UserJpaRepo.java @@ -9,5 +9,6 @@ @Repository public interface UserJpaRepo extends JpaRepository { Optional findByNickname(String name); + Optional findByEmail(String email); Optional findByNicknameAndProvider(String name, String provider); } diff --git a/src/main/java/org/prgrms/nabimarketbe/domain/user/service/SignService.java b/src/main/java/org/prgrms/nabimarketbe/domain/user/service/SignService.java index 8dd1c1c0..4f2cc528 100644 --- a/src/main/java/org/prgrms/nabimarketbe/domain/user/service/SignService.java +++ b/src/main/java/org/prgrms/nabimarketbe/domain/user/service/SignService.java @@ -2,47 +2,75 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.prgrms.nabimarketbe.global.security.jwt.dto.TokenRequestDto; +import org.prgrms.nabimarketbe.oauth2.kakao.dto.KakaoProfile; +import org.prgrms.nabimarketbe.oauth2.kakao.service.OAuth2Service; import org.prgrms.nabimarketbe.domain.user.dto.sign.UserSignupRequestDto; -import org.prgrms.nabimarketbe.domain.security.jwt.JwtProvider; -import org.prgrms.nabimarketbe.domain.security.entity.RefreshToken; -import org.prgrms.nabimarketbe.domain.security.repository.RefreshTokenJpaRepo; -import org.prgrms.nabimarketbe.domain.security.jwt.dto.TokenResponseDto; -import org.prgrms.nabimarketbe.domain.security.jwt.dto.TokenRequestDto; +import org.prgrms.nabimarketbe.global.security.jwt.provider.JwtProvider; +import org.prgrms.nabimarketbe.global.security.entity.RefreshToken; +import org.prgrms.nabimarketbe.oauth2.kakao.repository.RefreshTokenJpaRepo; +import org.prgrms.nabimarketbe.global.security.jwt.dto.TokenDto; import org.prgrms.nabimarketbe.domain.user.entity.User; import org.prgrms.nabimarketbe.domain.user.repository.UserJpaRepo; +import org.prgrms.nabimarketbe.global.util.ResponseFactory; +import org.prgrms.nabimarketbe.global.util.model.CommonResult; import org.springframework.security.core.Authentication; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.util.Optional; + @Slf4j @Service @RequiredArgsConstructor public class SignService { private final UserJpaRepo userJpaRepo; + private final OAuth2Service OAuth2Service; + + private final ResponseFactory responseFactory; + private final JwtProvider jwtProvider; private final RefreshTokenJpaRepo tokenJpaRepo; @Transactional - public Long socialSignup(UserSignupRequestDto userSignupRequestDto) { - if (userJpaRepo - .findByNicknameAndProvider(userSignupRequestDto.nickname(), userSignupRequestDto.provider()) - .isPresent() - ) throw new RuntimeException("이미 존재하는 회원입니다."); + public CommonResult signupBySocial(String accessToken) { + KakaoProfile kakaoProfile = OAuth2Service.getKakaoProfile(accessToken); + + if (kakaoProfile == null) throw new RuntimeException("카카오에 해당 회원이 없습니다."); + + CommonResult result = socialSignup(UserSignupRequestDto.builder() + .nickname(kakaoProfile.getProperties().getNickname()) + .provider("kakao") + .build()); + + return responseFactory.getSingleResult(result); + } + @Transactional + public CommonResult socialSignup(UserSignupRequestDto userSignupRequestDto) { + Optional user = userJpaRepo.findByNicknameAndProvider( + userSignupRequestDto.nickname(), + userSignupRequestDto.provider() + ); + + if (user.isPresent()) { + return responseFactory.getSingleResult(jwtProvider.createTokenDto(user.get().getUserId(), user.get().getRoles())); + } - return userJpaRepo.save(userSignupRequestDto.toEntity()).getUserId(); + userJpaRepo.save(userSignupRequestDto.toEntity()); + return responseFactory.getSingleResult(jwtProvider.createTokenDto(user.get().getUserId(), user.get().getRoles())); } @Transactional - public TokenResponseDto reissue(TokenRequestDto tokenRequestDto) { + public TokenDto reissue(TokenRequestDto tokenRequestDto) { // 만료된 refresh token 에러 - if (!jwtProvider.validationToken(tokenRequestDto.refreshToken())) { + if (!jwtProvider.validationToken(tokenRequestDto.getAccessToken())) { throw new RuntimeException("RefreshTokenException"); } // AccessToken 에서 Username (pk) 가져오기 - String accessToken = tokenRequestDto.accessToken(); + String accessToken = tokenRequestDto.getAccessToken(); Authentication authentication = jwtProvider.getAuthentication(accessToken); // user pk로 유저 검색 / repo 에 저장된 Refresh Token 이 없음 @@ -53,11 +81,11 @@ public TokenResponseDto reissue(TokenRequestDto tokenRequestDto) { .orElseThrow(() ->new RuntimeException("RefreshTokenException")); // 리프레시 토큰 불일치 에러 - if (!refreshToken.getToken().equals(tokenRequestDto.refreshToken())) + if (!refreshToken.getToken().equals(tokenRequestDto.getRefreshToken())) throw new RuntimeException("RefreshTokenException"); // AccessToken, RefreshToken 토큰 재발급, 리프레쉬 토큰 저장 - TokenResponseDto newCreatedToken = jwtProvider.createTokenDto(user.getUserId(), user.getRoles()); + TokenDto newCreatedToken = jwtProvider.createTokenDto(user.getUserId(), user.getRoles()); RefreshToken updateRefreshToken = refreshToken.updateToken(newCreatedToken.getRefreshToken()); tokenJpaRepo.save(updateRefreshToken); diff --git a/src/main/java/org/prgrms/nabimarketbe/domain/user/BaseEntity.java b/src/main/java/org/prgrms/nabimarketbe/global/BaseEntity.java similarity index 94% rename from src/main/java/org/prgrms/nabimarketbe/domain/user/BaseEntity.java rename to src/main/java/org/prgrms/nabimarketbe/global/BaseEntity.java index 42018aee..8f90987c 100644 --- a/src/main/java/org/prgrms/nabimarketbe/domain/user/BaseEntity.java +++ b/src/main/java/org/prgrms/nabimarketbe/global/BaseEntity.java @@ -1,5 +1,5 @@ -package org.prgrms.nabimarketbe.domain.user; +package org.prgrms.nabimarketbe.global; import lombok.Getter; import org.springframework.data.annotation.CreatedDate; diff --git a/src/main/java/org/prgrms/nabimarketbe/domain/security/SecurityConfiguration.java b/src/main/java/org/prgrms/nabimarketbe/global/config/SecurityConfiguration.java similarity index 78% rename from src/main/java/org/prgrms/nabimarketbe/domain/security/SecurityConfiguration.java rename to src/main/java/org/prgrms/nabimarketbe/global/config/SecurityConfiguration.java index 8ba6e7b4..6c490bb8 100644 --- a/src/main/java/org/prgrms/nabimarketbe/domain/security/SecurityConfiguration.java +++ b/src/main/java/org/prgrms/nabimarketbe/global/config/SecurityConfiguration.java @@ -1,8 +1,10 @@ -package org.prgrms.nabimarketbe.domain.security; +package org.prgrms.nabimarketbe.global.config; import lombok.RequiredArgsConstructor; -import org.prgrms.nabimarketbe.domain.security.jwt.JwtProvider; -import org.prgrms.nabimarketbe.domain.security.jwt.JwtAuthenticationFilter; +import org.prgrms.nabimarketbe.global.security.handler.CustomAccessDeniedHandler; +import org.prgrms.nabimarketbe.global.security.handler.CustomAuthenticationEntryPoint; +import org.prgrms.nabimarketbe.global.security.jwt.provider.JwtProvider; +import org.prgrms.nabimarketbe.global.security.jwt.filter.JwtAuthenticationFilter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpMethod; @@ -27,13 +29,14 @@ public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws http .httpBasic(Customizer.withDefaults()) .csrf().disable() - .sessionManagement(sessionManagement -> sessionManagement.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) + .sessionManagement(sessionManagement -> + sessionManagement.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) .authorizeRequests(authorizeRequests -> authorizeRequests .antMatchers(HttpMethod.POST, "/v1/signup", "/v1/login", "/v1/reissue", "/v1/social/**").permitAll() .antMatchers(HttpMethod.GET, "/oauth/kakao/**").permitAll() .antMatchers(HttpMethod.GET, "/exception/**").permitAll() - .anyRequest().hasRole("USER")) + .anyRequest ().hasRole("USER")) .exceptionHandling(exceptionHandling -> exceptionHandling .authenticationEntryPoint(customAuthenticationEntryPoint) .accessDeniedHandler(customAccessDeniedHandler) diff --git a/src/main/java/org/prgrms/nabimarketbe/domain/security/entity/RefreshToken.java b/src/main/java/org/prgrms/nabimarketbe/global/security/entity/RefreshToken.java similarity index 81% rename from src/main/java/org/prgrms/nabimarketbe/domain/security/entity/RefreshToken.java rename to src/main/java/org/prgrms/nabimarketbe/global/security/entity/RefreshToken.java index 008f2ecd..1e29a50f 100644 --- a/src/main/java/org/prgrms/nabimarketbe/domain/security/entity/RefreshToken.java +++ b/src/main/java/org/prgrms/nabimarketbe/global/security/entity/RefreshToken.java @@ -1,9 +1,8 @@ -package org.prgrms.nabimarketbe.domain.security.entity; +package org.prgrms.nabimarketbe.global.security.entity; -import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; -import org.prgrms.nabimarketbe.domain.user.BaseEntity; +import org.prgrms.nabimarketbe.global.BaseEntity; import javax.persistence.*; @@ -28,7 +27,6 @@ public RefreshToken updateToken(String token) { return this; } - @Builder public RefreshToken( Long key, String token diff --git a/src/main/java/org/prgrms/nabimarketbe/domain/security/CustomAccessDeniedHandler.java b/src/main/java/org/prgrms/nabimarketbe/global/security/handler/CustomAccessDeniedHandler.java similarity index 92% rename from src/main/java/org/prgrms/nabimarketbe/domain/security/CustomAccessDeniedHandler.java rename to src/main/java/org/prgrms/nabimarketbe/global/security/handler/CustomAccessDeniedHandler.java index 9acc3ac9..b6035e9b 100644 --- a/src/main/java/org/prgrms/nabimarketbe/domain/security/CustomAccessDeniedHandler.java +++ b/src/main/java/org/prgrms/nabimarketbe/global/security/handler/CustomAccessDeniedHandler.java @@ -1,4 +1,4 @@ -package org.prgrms.nabimarketbe.domain.security; +package org.prgrms.nabimarketbe.global.security.handler; import org.springframework.security.access.AccessDeniedException; import org.springframework.security.web.access.AccessDeniedHandler; diff --git a/src/main/java/org/prgrms/nabimarketbe/domain/security/CustomAuthenticationEntryPoint.java b/src/main/java/org/prgrms/nabimarketbe/global/security/handler/CustomAuthenticationEntryPoint.java similarity index 92% rename from src/main/java/org/prgrms/nabimarketbe/domain/security/CustomAuthenticationEntryPoint.java rename to src/main/java/org/prgrms/nabimarketbe/global/security/handler/CustomAuthenticationEntryPoint.java index d8682aa3..8baae370 100644 --- a/src/main/java/org/prgrms/nabimarketbe/domain/security/CustomAuthenticationEntryPoint.java +++ b/src/main/java/org/prgrms/nabimarketbe/global/security/handler/CustomAuthenticationEntryPoint.java @@ -1,4 +1,4 @@ -package org.prgrms.nabimarketbe.domain.security; +package org.prgrms.nabimarketbe.global.security.handler; import org.springframework.security.core.AuthenticationException; import org.springframework.security.web.AuthenticationEntryPoint; diff --git a/src/main/java/org/prgrms/nabimarketbe/global/security/jwt/dto/TokenRequestDto.java b/src/main/java/org/prgrms/nabimarketbe/global/security/jwt/dto/TokenRequestDto.java new file mode 100644 index 00000000..a7ecbe41 --- /dev/null +++ b/src/main/java/org/prgrms/nabimarketbe/global/security/jwt/dto/TokenRequestDto.java @@ -0,0 +1,20 @@ +package org.prgrms.nabimarketbe.global.security.jwt.dto; + +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@NoArgsConstructor +public class TokenRequestDto { + String accessToken; + String refreshToken; + + @Builder + public TokenRequestDto(String accessToken, String refreshToken) { + this.accessToken = accessToken; + this.refreshToken = refreshToken; + } +} diff --git a/src/main/java/org/prgrms/nabimarketbe/domain/security/jwt/JwtAuthenticationFilter.java b/src/main/java/org/prgrms/nabimarketbe/global/security/jwt/filter/JwtAuthenticationFilter.java similarity index 92% rename from src/main/java/org/prgrms/nabimarketbe/domain/security/jwt/JwtAuthenticationFilter.java rename to src/main/java/org/prgrms/nabimarketbe/global/security/jwt/filter/JwtAuthenticationFilter.java index 1f7ea868..c603a9bd 100644 --- a/src/main/java/org/prgrms/nabimarketbe/domain/security/jwt/JwtAuthenticationFilter.java +++ b/src/main/java/org/prgrms/nabimarketbe/global/security/jwt/filter/JwtAuthenticationFilter.java @@ -1,6 +1,7 @@ -package org.prgrms.nabimarketbe.domain.security.jwt; +package org.prgrms.nabimarketbe.global.security.jwt.filter; import lombok.extern.slf4j.Slf4j; +import org.prgrms.nabimarketbe.global.security.jwt.provider.JwtProvider; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.filter.GenericFilterBean; diff --git a/src/main/java/org/prgrms/nabimarketbe/domain/security/jwt/JwtProvider.java b/src/main/java/org/prgrms/nabimarketbe/global/security/jwt/provider/JwtProvider.java similarity index 94% rename from src/main/java/org/prgrms/nabimarketbe/domain/security/jwt/JwtProvider.java rename to src/main/java/org/prgrms/nabimarketbe/global/security/jwt/provider/JwtProvider.java index 578db2ef..99a18ea3 100644 --- a/src/main/java/org/prgrms/nabimarketbe/domain/security/jwt/JwtProvider.java +++ b/src/main/java/org/prgrms/nabimarketbe/global/security/jwt/provider/JwtProvider.java @@ -1,10 +1,10 @@ -package org.prgrms.nabimarketbe.domain.security.jwt; +package org.prgrms.nabimarketbe.global.security.jwt.provider; import io.jsonwebtoken.*; import io.jsonwebtoken.impl.Base64UrlCodec; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.prgrms.nabimarketbe.domain.security.jwt.dto.TokenResponseDto; +import org.prgrms.nabimarketbe.global.security.jwt.dto.TokenDto; import org.springframework.beans.factory.annotation.Value; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; @@ -37,7 +37,7 @@ protected void init() { } // Jwt 생성 - public TokenResponseDto createTokenDto(Long userPk, List roles) { + public TokenDto createTokenDto(Long userPk, List roles) { // Claims 에 user 구분을 위한 User pk 및 authorities 목록 삽입 Claims claims = Jwts.claims().setSubject(String.valueOf(userPk)); claims.put(ROLES, roles); @@ -59,7 +59,7 @@ public TokenResponseDto createTokenDto(Long userPk, List roles) { .signWith(SignatureAlgorithm.HS256, secretKey) .compact(); - return TokenResponseDto.builder() + return TokenDto.builder() .grantType("Bearer") .accessToken(accessToken) .refreshToken(refreshToken) diff --git a/src/main/java/org/prgrms/nabimarketbe/global/ResponseService.java b/src/main/java/org/prgrms/nabimarketbe/global/util/ResponseFactory.java similarity index 82% rename from src/main/java/org/prgrms/nabimarketbe/global/ResponseService.java rename to src/main/java/org/prgrms/nabimarketbe/global/util/ResponseFactory.java index 6fa005c7..2c866917 100644 --- a/src/main/java/org/prgrms/nabimarketbe/global/ResponseService.java +++ b/src/main/java/org/prgrms/nabimarketbe/global/util/ResponseFactory.java @@ -1,17 +1,17 @@ -package org.prgrms.nabimarketbe.global; +package org.prgrms.nabimarketbe.global.util; import lombok.extern.slf4j.Slf4j; -import org.prgrms.nabimarketbe.global.model.CommonResponse; -import org.prgrms.nabimarketbe.global.model.CommonResult; -import org.prgrms.nabimarketbe.global.model.ListResult; -import org.prgrms.nabimarketbe.global.model.SingleResult; +import org.prgrms.nabimarketbe.global.util.model.CommonResponse; +import org.prgrms.nabimarketbe.global.util.model.CommonResult; +import org.prgrms.nabimarketbe.global.util.model.ListResult; +import org.prgrms.nabimarketbe.global.util.model.SingleResult; import org.springframework.stereotype.Service; import java.util.List; @Service @Slf4j -public class ResponseService { +public class ResponseFactory { // 단일건 결과 처리 메소드 public SingleResult getSingleResult(T data) { SingleResult result = new SingleResult<>(); diff --git a/src/main/java/org/prgrms/nabimarketbe/global/model/CommonResponse.java b/src/main/java/org/prgrms/nabimarketbe/global/util/model/CommonResponse.java similarity index 82% rename from src/main/java/org/prgrms/nabimarketbe/global/model/CommonResponse.java rename to src/main/java/org/prgrms/nabimarketbe/global/util/model/CommonResponse.java index ad7194d4..6ea223e8 100644 --- a/src/main/java/org/prgrms/nabimarketbe/global/model/CommonResponse.java +++ b/src/main/java/org/prgrms/nabimarketbe/global/util/model/CommonResponse.java @@ -1,4 +1,4 @@ -package org.prgrms.nabimarketbe.global.model; +package org.prgrms.nabimarketbe.global.util.model; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/src/main/java/org/prgrms/nabimarketbe/global/model/CommonResult.java b/src/main/java/org/prgrms/nabimarketbe/global/util/model/CommonResult.java similarity index 76% rename from src/main/java/org/prgrms/nabimarketbe/global/model/CommonResult.java rename to src/main/java/org/prgrms/nabimarketbe/global/util/model/CommonResult.java index 59b0922e..fa551cad 100644 --- a/src/main/java/org/prgrms/nabimarketbe/global/model/CommonResult.java +++ b/src/main/java/org/prgrms/nabimarketbe/global/util/model/CommonResult.java @@ -1,4 +1,4 @@ -package org.prgrms.nabimarketbe.global.model; +package org.prgrms.nabimarketbe.global.util.model; import lombok.Getter; import lombok.Setter; diff --git a/src/main/java/org/prgrms/nabimarketbe/global/model/ListResult.java b/src/main/java/org/prgrms/nabimarketbe/global/util/model/ListResult.java similarity index 76% rename from src/main/java/org/prgrms/nabimarketbe/global/model/ListResult.java rename to src/main/java/org/prgrms/nabimarketbe/global/util/model/ListResult.java index 393684f6..b451233a 100644 --- a/src/main/java/org/prgrms/nabimarketbe/global/model/ListResult.java +++ b/src/main/java/org/prgrms/nabimarketbe/global/util/model/ListResult.java @@ -1,4 +1,4 @@ -package org.prgrms.nabimarketbe.global.model; +package org.prgrms.nabimarketbe.global.util.model; import lombok.Getter; import lombok.Setter; diff --git a/src/main/java/org/prgrms/nabimarketbe/global/model/SingleResult.java b/src/main/java/org/prgrms/nabimarketbe/global/util/model/SingleResult.java similarity index 72% rename from src/main/java/org/prgrms/nabimarketbe/global/model/SingleResult.java rename to src/main/java/org/prgrms/nabimarketbe/global/util/model/SingleResult.java index 3c8d9dd2..6e6ed43c 100644 --- a/src/main/java/org/prgrms/nabimarketbe/global/model/SingleResult.java +++ b/src/main/java/org/prgrms/nabimarketbe/global/util/model/SingleResult.java @@ -1,4 +1,4 @@ -package org.prgrms.nabimarketbe.global.model; +package org.prgrms.nabimarketbe.global.util.model; import lombok.Getter; import lombok.Setter; diff --git a/src/main/java/org/prgrms/nabimarketbe/member/domain/LoginResponseDTO.java b/src/main/java/org/prgrms/nabimarketbe/member/domain/LoginResponseDTO.java deleted file mode 100644 index 7a700911..00000000 --- a/src/main/java/org/prgrms/nabimarketbe/member/domain/LoginResponseDTO.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.prgrms.nabimarketbe.member.domain; - -public record LoginResponseDTO( - String jwtToken, - int userNum, - String accessToken, - String tokenType -) { -} diff --git a/src/main/java/org/prgrms/nabimarketbe/member/domain/GoogleOAuth2Token.java b/src/main/java/org/prgrms/nabimarketbe/oauth2/google/member/domain/GoogleOAuth2Token.java similarity index 70% rename from src/main/java/org/prgrms/nabimarketbe/member/domain/GoogleOAuth2Token.java rename to src/main/java/org/prgrms/nabimarketbe/oauth2/google/member/domain/GoogleOAuth2Token.java index 0d62bb41..c861d03c 100644 --- a/src/main/java/org/prgrms/nabimarketbe/member/domain/GoogleOAuth2Token.java +++ b/src/main/java/org/prgrms/nabimarketbe/oauth2/google/member/domain/GoogleOAuth2Token.java @@ -1,8 +1,8 @@ -package org.prgrms.nabimarketbe.member.domain; +package org.prgrms.nabimarketbe.oauth2.google.member.domain; import com.fasterxml.jackson.annotation.JsonProperty; -public record GoogleOAuth2Token( +public record GoogleOAuth2Token( // 이건 뭘까 @JsonProperty("access_token") String accessToken, diff --git a/src/main/java/org/prgrms/nabimarketbe/member/domain/GoogleUser.java b/src/main/java/org/prgrms/nabimarketbe/oauth2/google/member/domain/GoogleUser.java similarity index 73% rename from src/main/java/org/prgrms/nabimarketbe/member/domain/GoogleUser.java rename to src/main/java/org/prgrms/nabimarketbe/oauth2/google/member/domain/GoogleUser.java index 7395a136..b53a92ec 100644 --- a/src/main/java/org/prgrms/nabimarketbe/member/domain/GoogleUser.java +++ b/src/main/java/org/prgrms/nabimarketbe/oauth2/google/member/domain/GoogleUser.java @@ -1,4 +1,4 @@ -package org.prgrms.nabimarketbe.member.domain; +package org.prgrms.nabimarketbe.oauth2.google.member.domain; public record GoogleUser( String id, diff --git a/src/main/java/org/prgrms/nabimarketbe/oauth2/google/member/domain/LoginResponseDTO.java b/src/main/java/org/prgrms/nabimarketbe/oauth2/google/member/domain/LoginResponseDTO.java new file mode 100644 index 00000000..594cde25 --- /dev/null +++ b/src/main/java/org/prgrms/nabimarketbe/oauth2/google/member/domain/LoginResponseDTO.java @@ -0,0 +1,9 @@ +package org.prgrms.nabimarketbe.oauth2.google.member.domain; + +public record LoginResponseDTO( // 구글 토큰 반환용 + String jwtToken, + int userNum, + String accessToken, + String tokenType +) { +} diff --git a/src/main/java/org/prgrms/nabimarketbe/member/domain/OAuth2.java b/src/main/java/org/prgrms/nabimarketbe/oauth2/google/member/domain/OAuth2.java similarity index 89% rename from src/main/java/org/prgrms/nabimarketbe/member/domain/OAuth2.java rename to src/main/java/org/prgrms/nabimarketbe/oauth2/google/member/domain/OAuth2.java index 72b710cb..6539d992 100644 --- a/src/main/java/org/prgrms/nabimarketbe/member/domain/OAuth2.java +++ b/src/main/java/org/prgrms/nabimarketbe/oauth2/google/member/domain/OAuth2.java @@ -1,4 +1,4 @@ -package org.prgrms.nabimarketbe.member.domain; +package org.prgrms.nabimarketbe.oauth2.google.member.domain; import org.springframework.http.ResponseEntity; diff --git a/src/main/java/org/prgrms/nabimarketbe/member/domain/Role.java b/src/main/java/org/prgrms/nabimarketbe/oauth2/google/member/domain/Role.java similarity index 75% rename from src/main/java/org/prgrms/nabimarketbe/member/domain/Role.java rename to src/main/java/org/prgrms/nabimarketbe/oauth2/google/member/domain/Role.java index 8feffe49..b17f0f72 100644 --- a/src/main/java/org/prgrms/nabimarketbe/member/domain/Role.java +++ b/src/main/java/org/prgrms/nabimarketbe/oauth2/google/member/domain/Role.java @@ -1,4 +1,4 @@ -package org.prgrms.nabimarketbe.member.domain; +package org.prgrms.nabimarketbe.oauth2.google.member.domain; import lombok.Getter; import lombok.RequiredArgsConstructor; diff --git a/src/main/java/org/prgrms/nabimarketbe/member/dto/OAuth2Attributes.java b/src/main/java/org/prgrms/nabimarketbe/oauth2/google/member/dto/OAuth2Attributes.java similarity index 75% rename from src/main/java/org/prgrms/nabimarketbe/member/dto/OAuth2Attributes.java rename to src/main/java/org/prgrms/nabimarketbe/oauth2/google/member/dto/OAuth2Attributes.java index 73d4eac9..8b410963 100644 --- a/src/main/java/org/prgrms/nabimarketbe/member/dto/OAuth2Attributes.java +++ b/src/main/java/org/prgrms/nabimarketbe/oauth2/google/member/dto/OAuth2Attributes.java @@ -1,10 +1,9 @@ -package org.prgrms.nabimarketbe.member.dto; +package org.prgrms.nabimarketbe.oauth2.google.member.dto; +import java.util.Collections; import java.util.Map; -import org.prgrms.nabimarketbe.member.domain.Role; -import org.prgrms.nabimarketbe.member.domain.User; - +import org.prgrms.nabimarketbe.domain.user.entity.User; import lombok.Builder; import lombok.Getter; @@ -15,16 +14,16 @@ public class OAuth2Attributes { private String nameAttributeKey; private String name; private String email; - private String picture; + private String image_url; @Builder public OAuth2Attributes(Map attributes, String nameAttributeKey, String name, String email - ,String picture){ + ,String image_url){ this.attributes=attributes; this.nameAttributeKey=nameAttributeKey; this.name=name; this.email=email; - this.picture=picture; + this.image_url = image_url; } public static OAuth2Attributes of(String registrationId, String userNameAttributeName, Map attributes){ @@ -37,7 +36,7 @@ private static OAuth2Attributes ofGoogle(String userNameAttributeName, Map { - private final UserRepository userRepository; + private final UserJpaRepo userRepository; @Override public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException { @@ -44,7 +44,7 @@ public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2Authentic User user = saveIfNotPresent(attributes); return new DefaultOAuth2User(Collections.singleton( - new SimpleGrantedAuthority(user.getRoleKey())), + new SimpleGrantedAuthority(user.getRoles().get(0))), attributes.getAttributes(), attributes.getNameAttributeKey() ); diff --git a/src/main/java/org/prgrms/nabimarketbe/domain/security/oauth/controller/KOAuthController.java b/src/main/java/org/prgrms/nabimarketbe/oauth2/kakao/api/OAuth2Controller.java similarity index 55% rename from src/main/java/org/prgrms/nabimarketbe/domain/security/oauth/controller/KOAuthController.java rename to src/main/java/org/prgrms/nabimarketbe/oauth2/kakao/api/OAuth2Controller.java index a7de8549..5cd03b62 100644 --- a/src/main/java/org/prgrms/nabimarketbe/domain/security/oauth/controller/KOAuthController.java +++ b/src/main/java/org/prgrms/nabimarketbe/oauth2/kakao/api/OAuth2Controller.java @@ -1,33 +1,39 @@ -package org.prgrms.nabimarketbe.domain.security.oauth.controller; +package org.prgrms.nabimarketbe.oauth2.kakao.api; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.prgrms.nabimarketbe.global.model.CommonResult; -import org.prgrms.nabimarketbe.global.ResponseService; -import org.prgrms.nabimarketbe.domain.security.service.KakaoService; +import org.prgrms.nabimarketbe.global.security.jwt.dto.TokenDto; +import org.prgrms.nabimarketbe.global.security.jwt.dto.TokenRequestDto; +import org.prgrms.nabimarketbe.domain.user.service.SignService; +import org.prgrms.nabimarketbe.global.util.model.CommonResult; +import org.prgrms.nabimarketbe.global.util.ResponseFactory; +import org.prgrms.nabimarketbe.oauth2.kakao.service.OAuth2Service; +import org.prgrms.nabimarketbe.global.util.model.SingleResult; import org.springframework.beans.factory.annotation.Value; import org.springframework.core.env.Environment; import org.springframework.http.*; -import org.springframework.stereotype.Controller; import org.springframework.util.MultiValueMap; -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.*; import org.springframework.web.client.RestTemplate; import org.springframework.web.servlet.ModelAndView; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + @Slf4j -@Controller +@RestController @RequiredArgsConstructor @RequestMapping("/oauth/kakao") -public class KOAuthController { +public class OAuth2Controller { private final RestTemplate restTemplate; private final Environment env; - private final KakaoService kakaoService; + private final OAuth2Service OAuth2Service; + + private final SignService signService; - private final ResponseService responseService; + private final ResponseFactory responseFactory; @Value("${spring.url.base}") private String baseUrl; @@ -39,27 +45,26 @@ public class KOAuthController { private String kakaoRedirectUri; @GetMapping("/login") - public ModelAndView socialLogin(ModelAndView mav) { + public void socialLogin(HttpServletResponse response) throws IOException { StringBuilder loginUri = new StringBuilder() .append(env.getProperty("social.kakao.url.login")) .append("?response_type=code") .append("&client_id=").append(kakaoClientId) .append("&redirect_uri=").append(baseUrl).append(kakaoRedirectUri); - mav.addObject("loginUrl", loginUri); - mav.setViewName("social/login"); - - return mav; + response.sendRedirect(String.valueOf(loginUri)); } @GetMapping(value = "/redirect") - public ModelAndView redirectKakao( + public CommonResult redirectKakao( ModelAndView mav, @RequestParam String code) { - mav.addObject("authInfo", kakaoService.getKakaoTokenInfo(code)); - mav.setViewName("social/redirectKakao"); + //받은 token info 에서 acccess token 추출 + String accessToken = OAuth2Service.getKakaoTokenInfo(code).getAccess_token(); - return mav; + log.info(accessToken); + + return signService.signupBySocial(accessToken); } @GetMapping(value = "/unlink") @@ -78,9 +83,16 @@ public CommonResult unlinkKakao(@RequestParam String accessToken) { if (response.getStatusCode() == HttpStatus.OK) { log.info("unlink " + response.getBody()); - return responseService.getSuccessResult(); + return responseFactory.getSuccessResult(); } throw new RuntimeException("CommunicationException"); } + + //엑세스 토큰 만료시 회원 검증 후 리프레쉬 토큰을 검증해서 액세스 토큰과 리프레시 토큰을 재발급 + @PostMapping("/reissue") + public SingleResult reissue( + @RequestBody TokenRequestDto tokenRequestDto) { + return responseFactory.getSingleResult(signService.reissue(tokenRequestDto)); + } } diff --git a/src/main/java/org/prgrms/nabimarketbe/domain/security/oauth/dto/social/KakaoProfile.java b/src/main/java/org/prgrms/nabimarketbe/oauth2/kakao/dto/KakaoProfile.java similarity index 78% rename from src/main/java/org/prgrms/nabimarketbe/domain/security/oauth/dto/social/KakaoProfile.java rename to src/main/java/org/prgrms/nabimarketbe/oauth2/kakao/dto/KakaoProfile.java index 86672cf7..4bce3bf4 100644 --- a/src/main/java/org/prgrms/nabimarketbe/domain/security/oauth/dto/social/KakaoProfile.java +++ b/src/main/java/org/prgrms/nabimarketbe/oauth2/kakao/dto/KakaoProfile.java @@ -1,4 +1,4 @@ -package org.prgrms.nabimarketbe.domain.security.oauth.dto.social; +package org.prgrms.nabimarketbe.oauth2.kakao.dto; import lombok.Getter; import lombok.ToString; diff --git a/src/main/java/org/prgrms/nabimarketbe/domain/security/oauth/dto/social/RetKakaoOAuth.java b/src/main/java/org/prgrms/nabimarketbe/oauth2/kakao/dto/RetKakaoOAuth.java similarity index 80% rename from src/main/java/org/prgrms/nabimarketbe/domain/security/oauth/dto/social/RetKakaoOAuth.java rename to src/main/java/org/prgrms/nabimarketbe/oauth2/kakao/dto/RetKakaoOAuth.java index 765c98b3..b30ee4aa 100644 --- a/src/main/java/org/prgrms/nabimarketbe/domain/security/oauth/dto/social/RetKakaoOAuth.java +++ b/src/main/java/org/prgrms/nabimarketbe/oauth2/kakao/dto/RetKakaoOAuth.java @@ -1,4 +1,4 @@ -package org.prgrms.nabimarketbe.domain.security.oauth.dto.social; +package org.prgrms.nabimarketbe.oauth2.kakao.dto; import lombok.Getter; diff --git a/src/main/java/org/prgrms/nabimarketbe/domain/security/repository/RefreshTokenJpaRepo.java b/src/main/java/org/prgrms/nabimarketbe/oauth2/kakao/repository/RefreshTokenJpaRepo.java similarity index 64% rename from src/main/java/org/prgrms/nabimarketbe/domain/security/repository/RefreshTokenJpaRepo.java rename to src/main/java/org/prgrms/nabimarketbe/oauth2/kakao/repository/RefreshTokenJpaRepo.java index 3f410a8d..3654e063 100644 --- a/src/main/java/org/prgrms/nabimarketbe/domain/security/repository/RefreshTokenJpaRepo.java +++ b/src/main/java/org/prgrms/nabimarketbe/oauth2/kakao/repository/RefreshTokenJpaRepo.java @@ -1,6 +1,6 @@ -package org.prgrms.nabimarketbe.domain.security.repository; +package org.prgrms.nabimarketbe.oauth2.kakao.repository; -import org.prgrms.nabimarketbe.domain.security.entity.RefreshToken; +import org.prgrms.nabimarketbe.global.security.entity.RefreshToken; import org.springframework.data.jpa.repository.JpaRepository; import java.util.Optional; diff --git a/src/main/java/org/prgrms/nabimarketbe/domain/security/service/CustomUserDetailsService.java b/src/main/java/org/prgrms/nabimarketbe/oauth2/kakao/service/CustomUserDetailsService.java similarity index 93% rename from src/main/java/org/prgrms/nabimarketbe/domain/security/service/CustomUserDetailsService.java rename to src/main/java/org/prgrms/nabimarketbe/oauth2/kakao/service/CustomUserDetailsService.java index 22979ad2..7b480685 100644 --- a/src/main/java/org/prgrms/nabimarketbe/domain/security/service/CustomUserDetailsService.java +++ b/src/main/java/org/prgrms/nabimarketbe/oauth2/kakao/service/CustomUserDetailsService.java @@ -1,4 +1,4 @@ -package org.prgrms.nabimarketbe.domain.security.service; +package org.prgrms.nabimarketbe.oauth2.kakao.service; import lombok.RequiredArgsConstructor; import org.prgrms.nabimarketbe.domain.user.repository.UserJpaRepo; diff --git a/src/main/java/org/prgrms/nabimarketbe/domain/security/service/KakaoService.java b/src/main/java/org/prgrms/nabimarketbe/oauth2/kakao/service/OAuth2Service.java similarity index 92% rename from src/main/java/org/prgrms/nabimarketbe/domain/security/service/KakaoService.java rename to src/main/java/org/prgrms/nabimarketbe/oauth2/kakao/service/OAuth2Service.java index 2f527e47..951d7088 100644 --- a/src/main/java/org/prgrms/nabimarketbe/domain/security/service/KakaoService.java +++ b/src/main/java/org/prgrms/nabimarketbe/oauth2/kakao/service/OAuth2Service.java @@ -1,10 +1,10 @@ -package org.prgrms.nabimarketbe.domain.security.service; +package org.prgrms.nabimarketbe.oauth2.kakao.service; import com.google.gson.Gson; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.prgrms.nabimarketbe.domain.security.oauth.dto.social.KakaoProfile; -import org.prgrms.nabimarketbe.domain.security.oauth.dto.social.RetKakaoOAuth; +import org.prgrms.nabimarketbe.oauth2.kakao.dto.KakaoProfile; +import org.prgrms.nabimarketbe.oauth2.kakao.dto.RetKakaoOAuth; import org.springframework.beans.factory.annotation.Value; import org.springframework.core.env.Environment; import org.springframework.http.*; @@ -16,7 +16,7 @@ @Slf4j @RequiredArgsConstructor @Service -public class KakaoService { +public class OAuth2Service { private final Environment env; private final RestTemplate restTemplate; diff --git a/src/test/java/org/prgrms/nabimarketbe/oauth/controller/KOAuthControllerTest.java b/src/test/java/org/prgrms/nabimarketbe/oauth/controller/OAuth2ControllerTest.java similarity index 84% rename from src/test/java/org/prgrms/nabimarketbe/oauth/controller/KOAuthControllerTest.java rename to src/test/java/org/prgrms/nabimarketbe/oauth/controller/OAuth2ControllerTest.java index 70383c9d..b3032617 100644 --- a/src/test/java/org/prgrms/nabimarketbe/oauth/controller/KOAuthControllerTest.java +++ b/src/test/java/org/prgrms/nabimarketbe/oauth/controller/OAuth2ControllerTest.java @@ -1,23 +1,18 @@ package org.prgrms.nabimarketbe.oauth.controller; import org.assertj.core.api.Assertions; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.core.env.Environment; import org.springframework.http.*; -import org.springframework.test.context.junit4.SpringRunner; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.client.RestTemplate; -import static org.junit.Assert.*; - @SpringBootTest -@RunWith(SpringRunner.class) @Transactional -public class KOAuthControllerTest { +public class OAuth2ControllerTest { @Autowired private RestTemplate restTemplate; @@ -28,7 +23,7 @@ public class KOAuthControllerTest { private String kakaoClientId; private String kakaoRedirectUri; - @Before + @BeforeEach public void setUri() { baseUrl = env.getProperty("spring.url.base"); kakaoClientId = env.getProperty("social.kakao.client-id"); diff --git a/src/test/java/org/prgrms/nabimarketbe/user/controller/UserControllerTest.java b/src/test/java/org/prgrms/nabimarketbe/user/controller/UserControllerTest.java index 029ff6bb..f6282368 100644 --- a/src/test/java/org/prgrms/nabimarketbe/user/controller/UserControllerTest.java +++ b/src/test/java/org/prgrms/nabimarketbe/user/controller/UserControllerTest.java @@ -1,8 +1,7 @@ package org.prgrms.nabimarketbe.user.controller; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.prgrms.nabimarketbe.domain.user.entity.User; import org.prgrms.nabimarketbe.domain.user.repository.UserJpaRepo; import org.prgrms.nabimarketbe.domain.user.service.UserService; @@ -11,7 +10,6 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.test.context.support.WithMockUser; -import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.ResultActions; import org.springframework.transaction.annotation.Transactional; @@ -25,7 +23,6 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.*; -@RunWith(SpringRunner.class) @SpringBootTest @AutoConfigureMockMvc @Transactional @@ -46,7 +43,7 @@ public class UserControllerTest { private static int id; - @Before + @BeforeEach public void setUp() { User save = userJpaRepo.save(User.builder() .nickname("xinxinzara") diff --git a/src/test/java/org/prgrms/nabimarketbe/user/service/KakaoServiceTest.java b/src/test/java/org/prgrms/nabimarketbe/user/service/OAuth2ServiceTest.java similarity index 64% rename from src/test/java/org/prgrms/nabimarketbe/user/service/KakaoServiceTest.java rename to src/test/java/org/prgrms/nabimarketbe/user/service/OAuth2ServiceTest.java index a5ff2fca..c3133a37 100644 --- a/src/test/java/org/prgrms/nabimarketbe/user/service/KakaoServiceTest.java +++ b/src/test/java/org/prgrms/nabimarketbe/user/service/OAuth2ServiceTest.java @@ -1,32 +1,29 @@ package org.prgrms.nabimarketbe.user.service; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.prgrms.nabimarketbe.domain.security.service.KakaoService; -import org.prgrms.nabimarketbe.domain.security.oauth.dto.social.KakaoProfile; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.prgrms.nabimarketbe.oauth2.kakao.service.OAuth2Service; +import org.prgrms.nabimarketbe.oauth2.kakao.dto.KakaoProfile; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.core.env.Environment; import org.springframework.security.test.context.support.WithMockUser; -import org.springframework.test.context.junit4.SpringRunner; import static org.assertj.core.api.Assertions.*; -@RunWith(SpringRunner.class) @SpringBootTest @WithMockUser(username = "mockUser") -public class KakaoServiceTest { +public class OAuth2ServiceTest { @Autowired - private KakaoService kakaoService; + private OAuth2Service OAuth2Service; @Autowired Environment env; private static String accessToken; - @Before + @BeforeEach public void setToken() { accessToken = env.getProperty("social.kakao.accessToken"); } @@ -36,7 +33,7 @@ public void setToken() { { //given //when - KakaoProfile kakaoProfile = kakaoService.getKakaoProfile(accessToken); + KakaoProfile kakaoProfile = OAuth2Service.getKakaoProfile(accessToken); //then assertThat(kakaoProfile).isNotNull();