From f5dc23043267a3865a9fbc5c822b5e26b5f01384 Mon Sep 17 00:00:00 2001 From: Ji Seungmin Date: Mon, 18 Dec 2023 14:42:45 +0900 Subject: [PATCH 01/13] =?UTF-8?q?chore:=20spring=20boot=20version=20?= =?UTF-8?q?=EC=97=85=EA=B7=B8=EB=A0=88=EC=9D=B4=EB=93=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 6888a3b..c6cc8e0 100644 --- a/build.gradle +++ b/build.gradle @@ -6,8 +6,8 @@ buildscript { plugins { id 'java' - id 'org.springframework.boot' version '2.7.12' - id 'io.spring.dependency-management' version '1.0.15.RELEASE' + id 'org.springframework.boot' version '3.2.0' + id 'io.spring.dependency-management' version '1.1.4' //querydsl 추가 id "com.ewerk.gradle.plugins.querydsl" version "1.0.10" } From d5325b6dc22866e7b9692e9127df57002bf8b186 Mon Sep 17 00:00:00 2001 From: Ji Seungmin Date: Mon, 18 Dec 2023 15:01:59 +0900 Subject: [PATCH 02/13] =?UTF-8?q?fix:=20JsonObject=EC=97=90=EC=84=9C=20Obj?= =?UTF-8?q?ectMapper=EB=A1=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 3 ++- .../JwtAuthenticationFilter.java | 11 ++++++----- .../JwtKakaoAuthenticationFilter.java | 10 ++++------ .../JwtAuthorizationRsaFilter.java | 8 ++++---- .../CustomAuthenticationEntryPoint.java | 18 +++++++++++------- .../CustomAuthenticationFailureHandler.java | 18 +++++++++++------- 6 files changed, 38 insertions(+), 30 deletions(-) diff --git a/build.gradle b/build.gradle index c6cc8e0..fcc49fa 100644 --- a/build.gradle +++ b/build.gradle @@ -54,7 +54,8 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-security' //JSON Parse 라이브러리 - implementation 'com.google.code.gson:gson:2.8.9' + implementation 'com.fasterxml.jackson.core:jackson-databind' + implementation 'com.google.code.gson:gson' // validation implementation 'org.springframework.boot:spring-boot-starter-validation' diff --git a/src/main/java/com/umc/refit/web/filter/authentication/JwtAuthenticationFilter.java b/src/main/java/com/umc/refit/web/filter/authentication/JwtAuthenticationFilter.java index 08ee4d6..b7bfbdd 100644 --- a/src/main/java/com/umc/refit/web/filter/authentication/JwtAuthenticationFilter.java +++ b/src/main/java/com/umc/refit/web/filter/authentication/JwtAuthenticationFilter.java @@ -9,6 +9,10 @@ import com.umc.refit.web.service.MemberService; import com.umc.refit.web.service.RefreshTokenService; import com.umc.refit.web.signature.SecuritySigner; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; @@ -18,10 +22,6 @@ import org.springframework.security.core.userdetails.User; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Optional; @@ -68,7 +68,8 @@ public Authentication attemptAuthentication(HttpServletRequest request, HttpServ /*일반 로그인 인증 성공시 토큰 발행하는 메소드*/ @Override - protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws ServletException, IOException { + protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws + ServletException, IOException { User user = (User) authResult.getPrincipal(); try { //엑세스 토큰 및 리프레쉬 토큰 발행 diff --git a/src/main/java/com/umc/refit/web/filter/authentication/JwtKakaoAuthenticationFilter.java b/src/main/java/com/umc/refit/web/filter/authentication/JwtKakaoAuthenticationFilter.java index 0b70e16..bf486a6 100644 --- a/src/main/java/com/umc/refit/web/filter/authentication/JwtKakaoAuthenticationFilter.java +++ b/src/main/java/com/umc/refit/web/filter/authentication/JwtKakaoAuthenticationFilter.java @@ -11,21 +11,19 @@ import com.umc.refit.web.service.MemberService; import com.umc.refit.web.service.RefreshTokenService; import com.umc.refit.web.signature.SecuritySigner; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; -import org.springframework.beans.factory.annotation.Value; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.userdetails.User; -import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; diff --git a/src/main/java/com/umc/refit/web/filter/authorization/JwtAuthorizationRsaFilter.java b/src/main/java/com/umc/refit/web/filter/authorization/JwtAuthorizationRsaFilter.java index 2186a6c..ce5dd82 100644 --- a/src/main/java/com/umc/refit/web/filter/authorization/JwtAuthorizationRsaFilter.java +++ b/src/main/java/com/umc/refit/web/filter/authorization/JwtAuthorizationRsaFilter.java @@ -4,6 +4,10 @@ import com.nimbusds.jose.jwk.RSAKey; import com.nimbusds.jwt.SignedJWT; import com.umc.refit.exception.ExceptionType; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; @@ -12,10 +16,6 @@ import org.springframework.util.AntPathMatcher; import org.springframework.web.filter.OncePerRequestFilter; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Date; import java.util.List; diff --git a/src/main/java/com/umc/refit/web/filter/exception/CustomAuthenticationEntryPoint.java b/src/main/java/com/umc/refit/web/filter/exception/CustomAuthenticationEntryPoint.java index 4712835..153df13 100644 --- a/src/main/java/com/umc/refit/web/filter/exception/CustomAuthenticationEntryPoint.java +++ b/src/main/java/com/umc/refit/web/filter/exception/CustomAuthenticationEntryPoint.java @@ -1,15 +1,16 @@ package com.umc.refit.web.filter.exception; -import com.nimbusds.jose.shaded.json.JSONObject; +import com.fasterxml.jackson.databind.ObjectMapper; import com.umc.refit.exception.ExceptionType; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import lombok.extern.slf4j.Slf4j; import org.springframework.security.core.AuthenticationException; import org.springframework.security.web.AuthenticationEntryPoint; import org.springframework.stereotype.Component; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import java.io.IOException; +import java.util.HashMap; @Slf4j @Component @@ -25,9 +26,12 @@ private void setResponse(HttpServletResponse response, ExceptionType errorType) response.setContentType("application/json;charset=UTF-8"); response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); - JSONObject responseJson = new JSONObject(); - responseJson.put("errorMessage", errorType.getErrorMessage()); - responseJson.put("code", errorType.getCode()); - response.getWriter().print(responseJson); + ObjectMapper mapper = new ObjectMapper(); + HashMap errorResponse = new HashMap<>(); + errorResponse.put("errorMessage", errorType.getErrorMessage()); + errorResponse.put("code", errorType.getCode()); + + String jsonResponse = mapper.writeValueAsString(errorResponse); + response.getWriter().print(jsonResponse); } } diff --git a/src/main/java/com/umc/refit/web/filter/exception/CustomAuthenticationFailureHandler.java b/src/main/java/com/umc/refit/web/filter/exception/CustomAuthenticationFailureHandler.java index f00a513..ad676ef 100644 --- a/src/main/java/com/umc/refit/web/filter/exception/CustomAuthenticationFailureHandler.java +++ b/src/main/java/com/umc/refit/web/filter/exception/CustomAuthenticationFailureHandler.java @@ -1,7 +1,9 @@ package com.umc.refit.web.filter.exception; -import com.nimbusds.jose.shaded.json.JSONObject; +import com.fasterxml.jackson.databind.ObjectMapper; import com.umc.refit.exception.member.LoginException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.http.HttpStatus; import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.core.AuthenticationException; @@ -9,9 +11,8 @@ import org.springframework.security.web.authentication.AuthenticationFailureHandler; import org.springframework.stereotype.Component; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import java.io.IOException; +import java.util.HashMap; import static com.umc.refit.exception.ExceptionType.LOGIN_FAILED; import static com.umc.refit.exception.ExceptionType.LOGIN_FAILED_ALL; @@ -40,9 +41,12 @@ public void onAuthenticationFailure(HttpServletRequest request, HttpServletRespo code = LOGIN_FAILED_ALL.getCode(); } - JSONObject responseJson = new JSONObject(); - responseJson.put("errorMessage", errorMessage); - responseJson.put("code", code); - response.getWriter().print(responseJson); + ObjectMapper mapper = new ObjectMapper(); + HashMap errorResponse = new HashMap<>(); + errorResponse.put("errorMessage", errorMessage); + errorResponse.put("code", code); + + String jsonResponse = mapper.writeValueAsString(errorResponse); + response.getWriter().print(jsonResponse); } } \ No newline at end of file From 820b37f9b9bd670ef57fead273f2c05de6e1df72 Mon Sep 17 00:00:00 2001 From: Ji Seungmin Date: Mon, 18 Dec 2023 16:27:41 +0900 Subject: [PATCH 03/13] =?UTF-8?q?chore:=20=EC=8A=A4=ED=94=84=EB=A7=81=206?= =?UTF-8?q?=EB=B2=84=EC=A0=84=EC=9C=BC=EB=A1=9C=20=EB=A7=88=EC=9D=B4?= =?UTF-8?q?=EA=B7=B8=EB=A0=88=EC=9D=B4=EC=85=98=20=EC=8B=9C=20=EB=B0=9C?= =?UTF-8?q?=EC=83=9D=ED=95=98=EB=8A=94=20=EB=B9=8C=EB=93=9C=20=EC=98=A4?= =?UTF-8?q?=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 39 ++++++------------ .../dto/clothe/RegisterClotheRequestDto.java | 2 +- .../clothe/UpdateClotheGoalRequestDto.java | 4 +- .../dto/clothe/UpdateClotheRequestDto.java | 4 +- .../domain/dto/community/ReportMemDto.java | 4 -- .../dto/mypage/UpdateMyInfoRequestDto.java | 3 +- .../refit/domain/entity/BaseTimeEntity.java | 6 +-- .../com/umc/refit/domain/entity/Block.java | 2 +- .../com/umc/refit/domain/entity/Clothe.java | 2 +- .../com/umc/refit/domain/entity/Member.java | 2 +- .../umc/refit/domain/entity/PostImage.java | 2 +- .../com/umc/refit/domain/entity/Posts.java | 2 +- .../com/umc/refit/domain/entity/Question.java | 2 +- .../umc/refit/domain/entity/ReportMem.java | 2 +- .../com/umc/refit/domain/entity/Scrap.java | 2 +- .../handler/ClotheExceptionHandler.java | 3 +- .../handler/CommunityExceptionHandler.java | 2 +- .../handler/MemberExceptionHandler.java | 2 +- .../handler/MyInfoExceptionHandler.java | 2 +- .../com/umc/refit/web/config/S3Config.java | 35 ++++++++++++++++ .../umc/refit/web/config/SignatureConfig.java | 1 - ...eServer.java => SpringSecurityConfig.java} | 41 ++++++------------- .../umc/refit/web/config/ThymeleafConfig.java | 14 +++++++ .../refit/web/controller/BlockController.java | 2 +- .../web/controller/ClotheController.java | 4 +- .../web/controller/CommunityController.java | 2 +- .../web/controller/MemberController.java | 7 ++-- .../web/controller/MypageController.java | 4 +- .../refit/web/controller/OauthController.java | 2 +- .../web/controller/ReportMemController.java | 4 +- .../refit/web/controller/TradeController.java | 2 +- .../JwtAuthenticationFilter.java | 4 -- .../JwtKakaoAuthenticationFilter.java | 2 - .../JwtAuthorizationRsaFilter.java | 15 +++---- .../repository/CommunityRepositoryImpl.java | 3 +- .../umc/refit/web/service/BlockService.java | 2 +- .../umc/refit/web/service/CmImgService.java | 2 +- .../refit/web/service/CommunityService.java | 2 +- .../umc/refit/web/service/EmailService.java | 9 ++-- .../refit/web/service/ReportMemService.java | 2 +- .../refit/web/service/S3UploadService.java | 6 +-- .../umc/refit/web/service/ScrapService.java | 2 +- src/main/resources/application.yml | 2 +- 43 files changed, 124 insertions(+), 132 deletions(-) create mode 100644 src/main/java/com/umc/refit/web/config/S3Config.java rename src/main/java/com/umc/refit/web/config/{OAuth2ResourceServer.java => SpringSecurityConfig.java} (66%) create mode 100644 src/main/java/com/umc/refit/web/config/ThymeleafConfig.java diff --git a/build.gradle b/build.gradle index fcc49fa..8e7611e 100644 --- a/build.gradle +++ b/build.gradle @@ -1,15 +1,7 @@ -buildscript { - ext { - queryDslVersion = "5.0.0" - } -} - plugins { id 'java' id 'org.springframework.boot' version '3.2.0' id 'io.spring.dependency-management' version '1.1.4' - //querydsl 추가 - id "com.ewerk.gradle.plugins.querydsl" version "1.0.10" } jar { @@ -18,10 +10,7 @@ jar { group = 'com.umc' version = '0.0.1-SNAPSHOT' - -java { - sourceCompatibility = '17' -} +sourceCompatibility = '17' configurations { compileOnly { @@ -44,6 +33,7 @@ dependencies { //메일 전송 라이브러리 implementation group: 'org.springframework.boot', name: 'spring-boot-starter-mail', version: '2.5.5' + implementation group: 'com.sun.mail', name: 'jakarta.mail', version: '2.0.1' //타임리프 라이브러리® implementation group: 'org.springframework.boot', name: 'spring-boot-starter-thymeleaf', version: '2.7.12' @@ -67,10 +57,10 @@ dependencies { implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE' //querydsl 추가 - implementation "com.querydsl:querydsl-jpa:${queryDslVersion}" // querydsl 라이브러리 - annotationProcessor "com.querydsl:querydsl-apt:${queryDslVersion}" // Querydsl 관련 코드 생성 기능 제공 - - + implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta' + annotationProcessor "com.querydsl:querydsl-apt:5.0.0:jakarta" + annotationProcessor "jakarta.annotation:jakarta.annotation-api" + annotationProcessor "jakarta.persistence:jakarta.persistence-api" } tasks.named('test') { @@ -78,21 +68,16 @@ tasks.named('test') { } -//querydsl 추가 시작 (위에 plugin 추가 부분과 맞물림) def querydslDir = "$buildDir/generated/querydsl" -querydsl { - jpa = true - querydslSourcesDir = querydslDir -} -sourceSets { // IDE의 소스 폴더에 자동으로 넣어준다. - main.java.srcDir querydslDir +sourceSets { + main.java.srcDirs += [ querydslDir ] } -configurations { - querydsl.extendsFrom compileClasspath // 컴파일이 될때 같이 수행 +tasks.withType(JavaCompile) { + options.annotationProcessorGeneratedSourcesDirectory = file(querydslDir) } -compileQuerydsl { - options.annotationProcessorPath = configurations.querydsl // Q파일을 생성해준다. +clean.doLast { + file(querydslDir).deleteDir() } \ No newline at end of file diff --git a/src/main/java/com/umc/refit/domain/dto/clothe/RegisterClotheRequestDto.java b/src/main/java/com/umc/refit/domain/dto/clothe/RegisterClotheRequestDto.java index b0a4f3e..0cf7fbe 100644 --- a/src/main/java/com/umc/refit/domain/dto/clothe/RegisterClotheRequestDto.java +++ b/src/main/java/com/umc/refit/domain/dto/clothe/RegisterClotheRequestDto.java @@ -6,7 +6,7 @@ import lombok.*; import org.hibernate.validator.constraints.Range; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.*; @Getter @Setter diff --git a/src/main/java/com/umc/refit/domain/dto/clothe/UpdateClotheGoalRequestDto.java b/src/main/java/com/umc/refit/domain/dto/clothe/UpdateClotheGoalRequestDto.java index d0320b9..d7b7980 100644 --- a/src/main/java/com/umc/refit/domain/dto/clothe/UpdateClotheGoalRequestDto.java +++ b/src/main/java/com/umc/refit/domain/dto/clothe/UpdateClotheGoalRequestDto.java @@ -2,9 +2,7 @@ import lombok.*; -import javax.validation.constraints.Max; -import javax.validation.constraints.Min; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.*; @Getter @Setter diff --git a/src/main/java/com/umc/refit/domain/dto/clothe/UpdateClotheRequestDto.java b/src/main/java/com/umc/refit/domain/dto/clothe/UpdateClotheRequestDto.java index b7c8f38..d7df853 100644 --- a/src/main/java/com/umc/refit/domain/dto/clothe/UpdateClotheRequestDto.java +++ b/src/main/java/com/umc/refit/domain/dto/clothe/UpdateClotheRequestDto.java @@ -2,9 +2,7 @@ import lombok.*; -import javax.validation.constraints.Max; -import javax.validation.constraints.Min; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.*; @Getter @Setter diff --git a/src/main/java/com/umc/refit/domain/dto/community/ReportMemDto.java b/src/main/java/com/umc/refit/domain/dto/community/ReportMemDto.java index 4679c37..9498036 100644 --- a/src/main/java/com/umc/refit/domain/dto/community/ReportMemDto.java +++ b/src/main/java/com/umc/refit/domain/dto/community/ReportMemDto.java @@ -4,10 +4,6 @@ import lombok.Getter; import lombok.Setter; -import javax.validation.constraints.Max; -import javax.validation.constraints.Min; -import javax.validation.constraints.NotNull; - @Getter @Setter public class ReportMemDto { diff --git a/src/main/java/com/umc/refit/domain/dto/mypage/UpdateMyInfoRequestDto.java b/src/main/java/com/umc/refit/domain/dto/mypage/UpdateMyInfoRequestDto.java index 04797bc..3428ef6 100644 --- a/src/main/java/com/umc/refit/domain/dto/mypage/UpdateMyInfoRequestDto.java +++ b/src/main/java/com/umc/refit/domain/dto/mypage/UpdateMyInfoRequestDto.java @@ -1,8 +1,7 @@ package com.umc.refit.domain.dto.mypage; import lombok.*; - -import javax.validation.constraints.Size; +import jakarta.validation.constraints.*; @Getter @Setter diff --git a/src/main/java/com/umc/refit/domain/entity/BaseTimeEntity.java b/src/main/java/com/umc/refit/domain/entity/BaseTimeEntity.java index 0104fd7..421e6f9 100644 --- a/src/main/java/com/umc/refit/domain/entity/BaseTimeEntity.java +++ b/src/main/java/com/umc/refit/domain/entity/BaseTimeEntity.java @@ -1,13 +1,13 @@ package com.umc.refit.domain.entity; +import jakarta.persistence.Column; +import jakarta.persistence.EntityListeners; +import jakarta.persistence.MappedSuperclass; import lombok.Getter; import org.springframework.data.annotation.CreatedDate; import org.springframework.data.annotation.LastModifiedDate; import org.springframework.data.jpa.domain.support.AuditingEntityListener; -import javax.persistence.Column; -import javax.persistence.EntityListeners; -import javax.persistence.MappedSuperclass; import java.time.LocalDateTime; @Getter diff --git a/src/main/java/com/umc/refit/domain/entity/Block.java b/src/main/java/com/umc/refit/domain/entity/Block.java index 522c98f..d780925 100644 --- a/src/main/java/com/umc/refit/domain/entity/Block.java +++ b/src/main/java/com/umc/refit/domain/entity/Block.java @@ -5,7 +5,7 @@ import lombok.Getter; import lombok.NoArgsConstructor; -import javax.persistence.*; +import jakarta.persistence.*; @Entity @Getter diff --git a/src/main/java/com/umc/refit/domain/entity/Clothe.java b/src/main/java/com/umc/refit/domain/entity/Clothe.java index bd07037..05fcf53 100644 --- a/src/main/java/com/umc/refit/domain/entity/Clothe.java +++ b/src/main/java/com/umc/refit/domain/entity/Clothe.java @@ -1,13 +1,13 @@ package com.umc.refit.domain.entity; import com.umc.refit.domain.dto.clothe.*; +import jakarta.persistence.*; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.extern.slf4j.Slf4j; -import javax.persistence.*; import java.time.LocalDate; @Slf4j diff --git a/src/main/java/com/umc/refit/domain/entity/Member.java b/src/main/java/com/umc/refit/domain/entity/Member.java index 9e69c99..ad314a5 100644 --- a/src/main/java/com/umc/refit/domain/entity/Member.java +++ b/src/main/java/com/umc/refit/domain/entity/Member.java @@ -9,7 +9,7 @@ import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.UserDetails; -import javax.persistence.*; +import jakarta.persistence.*; import java.time.LocalDate; import java.util.ArrayList; import java.util.Collection; diff --git a/src/main/java/com/umc/refit/domain/entity/PostImage.java b/src/main/java/com/umc/refit/domain/entity/PostImage.java index 63b25dc..2420703 100644 --- a/src/main/java/com/umc/refit/domain/entity/PostImage.java +++ b/src/main/java/com/umc/refit/domain/entity/PostImage.java @@ -5,7 +5,7 @@ import lombok.Getter; import lombok.NoArgsConstructor; -import javax.persistence.*; +import jakarta.persistence.*; @Entity @Getter diff --git a/src/main/java/com/umc/refit/domain/entity/Posts.java b/src/main/java/com/umc/refit/domain/entity/Posts.java index 2b655de..d8e3521 100644 --- a/src/main/java/com/umc/refit/domain/entity/Posts.java +++ b/src/main/java/com/umc/refit/domain/entity/Posts.java @@ -5,7 +5,7 @@ import lombok.Getter; import lombok.NoArgsConstructor; -import javax.persistence.*; +import jakarta.persistence.*; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/com/umc/refit/domain/entity/Question.java b/src/main/java/com/umc/refit/domain/entity/Question.java index 70c882f..358aabf 100644 --- a/src/main/java/com/umc/refit/domain/entity/Question.java +++ b/src/main/java/com/umc/refit/domain/entity/Question.java @@ -6,7 +6,7 @@ import lombok.NoArgsConstructor; import lombok.extern.slf4j.Slf4j; -import javax.persistence.*; +import jakarta.persistence.*; @Slf4j @Getter diff --git a/src/main/java/com/umc/refit/domain/entity/ReportMem.java b/src/main/java/com/umc/refit/domain/entity/ReportMem.java index 6f082cf..a37632c 100644 --- a/src/main/java/com/umc/refit/domain/entity/ReportMem.java +++ b/src/main/java/com/umc/refit/domain/entity/ReportMem.java @@ -5,7 +5,7 @@ import lombok.Getter; import lombok.NoArgsConstructor; -import javax.persistence.*; +import jakarta.persistence.*; @Entity @Getter diff --git a/src/main/java/com/umc/refit/domain/entity/Scrap.java b/src/main/java/com/umc/refit/domain/entity/Scrap.java index cce0ffe..408a7c1 100644 --- a/src/main/java/com/umc/refit/domain/entity/Scrap.java +++ b/src/main/java/com/umc/refit/domain/entity/Scrap.java @@ -5,7 +5,7 @@ import lombok.Getter; import lombok.NoArgsConstructor; -import javax.persistence.*; +import jakarta.persistence.*; @Entity @Getter diff --git a/src/main/java/com/umc/refit/exception/handler/ClotheExceptionHandler.java b/src/main/java/com/umc/refit/exception/handler/ClotheExceptionHandler.java index f6235d1..ab1a111 100644 --- a/src/main/java/com/umc/refit/exception/handler/ClotheExceptionHandler.java +++ b/src/main/java/com/umc/refit/exception/handler/ClotheExceptionHandler.java @@ -8,8 +8,7 @@ import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestControllerAdvice; - -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; @Slf4j @RestControllerAdvice(basePackageClasses = ClotheController.class) diff --git a/src/main/java/com/umc/refit/exception/handler/CommunityExceptionHandler.java b/src/main/java/com/umc/refit/exception/handler/CommunityExceptionHandler.java index 414a043..e5bbdc8 100644 --- a/src/main/java/com/umc/refit/exception/handler/CommunityExceptionHandler.java +++ b/src/main/java/com/umc/refit/exception/handler/CommunityExceptionHandler.java @@ -10,7 +10,7 @@ import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestControllerAdvice; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; @Slf4j @RestControllerAdvice diff --git a/src/main/java/com/umc/refit/exception/handler/MemberExceptionHandler.java b/src/main/java/com/umc/refit/exception/handler/MemberExceptionHandler.java index d663dd0..3582804 100644 --- a/src/main/java/com/umc/refit/exception/handler/MemberExceptionHandler.java +++ b/src/main/java/com/umc/refit/exception/handler/MemberExceptionHandler.java @@ -9,7 +9,7 @@ import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestControllerAdvice; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; @Slf4j @RestControllerAdvice diff --git a/src/main/java/com/umc/refit/exception/handler/MyInfoExceptionHandler.java b/src/main/java/com/umc/refit/exception/handler/MyInfoExceptionHandler.java index e223cce..895fa19 100644 --- a/src/main/java/com/umc/refit/exception/handler/MyInfoExceptionHandler.java +++ b/src/main/java/com/umc/refit/exception/handler/MyInfoExceptionHandler.java @@ -8,7 +8,7 @@ import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestControllerAdvice; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; @Slf4j @RestControllerAdvice diff --git a/src/main/java/com/umc/refit/web/config/S3Config.java b/src/main/java/com/umc/refit/web/config/S3Config.java new file mode 100644 index 0000000..5953bf4 --- /dev/null +++ b/src/main/java/com/umc/refit/web/config/S3Config.java @@ -0,0 +1,35 @@ +package com.umc.refit.web.config; + +import com.amazonaws.auth.AWSCredentials; +import com.amazonaws.auth.AWSStaticCredentialsProvider; +import com.amazonaws.auth.BasicAWSCredentials; +import com.amazonaws.services.s3.AmazonS3; +import com.amazonaws.services.s3.AmazonS3ClientBuilder; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.jpa.repository.config.EnableJpaAuditing; + +@Configuration +public class S3Config { + @Value("${cloud.aws.credentials.access-key}") + private String accessKey; + + @Value("${cloud.aws.credentials.secret-key}") + private String secretKey; + + @Value("${cloud.aws.region.static}") + private String region; + + @Bean + public AmazonS3 amazonS3Client() { + AWSCredentials credentials = new BasicAWSCredentials(accessKey, secretKey); + + return AmazonS3ClientBuilder + .standard() + .withCredentials(new AWSStaticCredentialsProvider(credentials)) + .withRegion(region) + .build(); + } + +} \ No newline at end of file diff --git a/src/main/java/com/umc/refit/web/config/SignatureConfig.java b/src/main/java/com/umc/refit/web/config/SignatureConfig.java index 3abe5c2..1a0fac4 100644 --- a/src/main/java/com/umc/refit/web/config/SignatureConfig.java +++ b/src/main/java/com/umc/refit/web/config/SignatureConfig.java @@ -18,7 +18,6 @@ public RSASecuritySigner rsaSecuritySigner() { return new RSASecuritySigner(); } - /*RSA 키 생성*/ @Bean public RSAKey rsaKey512() throws JOSEException { return new RSAKeyGenerator(2048) diff --git a/src/main/java/com/umc/refit/web/config/OAuth2ResourceServer.java b/src/main/java/com/umc/refit/web/config/SpringSecurityConfig.java similarity index 66% rename from src/main/java/com/umc/refit/web/config/OAuth2ResourceServer.java rename to src/main/java/com/umc/refit/web/config/SpringSecurityConfig.java index 723f0b3..f27f58b 100644 --- a/src/main/java/com/umc/refit/web/config/OAuth2ResourceServer.java +++ b/src/main/java/com/umc/refit/web/config/SpringSecurityConfig.java @@ -21,7 +21,7 @@ @EnableWebSecurity @RequiredArgsConstructor -public class OAuth2ResourceServer { +public class SpringSecurityConfig { private final RSASecuritySigner rsaSecuritySigner; private final RSAKey rsaKey; @@ -29,51 +29,36 @@ public class OAuth2ResourceServer { private final CustomAuthenticationFailureHandler authFailureHandler; private final MemberService memberService; private final RefreshTokenService refreshTokenService; + private final CustomAuthenticationEntryPoint authenticationEntryPoint; + + private String[] permitAllUrlPatterns() { + return new String[] { + "/auth/logout", "/auth/join", "/auth/email", "/auth/find/id", + "/auth/reset/password", "/static/**", "/*.html", "/oauth2/fcm", + "/oauth2/image", "/auth/join/name" + }; + } @Bean SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { - //세션을 사용하지 않음 - http.csrf().disable(); - http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); - - //인증을 거치지 않을 URL 처리 및 인증, 인가 예외 EntryPoint 등록 - http.authorizeRequests((requests) -> - - requests.antMatchers("/auth/logout" //로그아웃 - , "/auth/join" //회원 가입 - , "/auth/email" //이메일 찾기 - , "/auth/find/id" //아이디 찾기 - , "/auth/reset/password" //패스워드 찾기 - , "/static/**" //카카오 주소 api - , "/*.html" //카카오 주소 api - , "/oauth2/fcm" - , "/oauth2/image" - , "/auth/join/name" -// , "/**" //임시로 모든 인증 처리 제외 - ).permitAll() + http.authorizeHttpRequests((requests) -> + requests.requestMatchers(permitAllUrlPatterns()).permitAll() .anyRequest().authenticated()) + .exceptionHandling(error -> error.authenticationEntryPoint(authenticationEntryPoint)); - .exceptionHandling().authenticationEntryPoint(new CustomAuthenticationEntryPoint()); - - //사용자 정보 로드해서 객체 생성 http.userDetailsService(userDetailsService); - //일반 로그인 URL 설정 JwtAuthenticationFilter jwtAuthenticationFilter = - new JwtAuthenticationFilter(http, rsaSecuritySigner, rsaKey, memberService, refreshTokenService); - jwtAuthenticationFilter.setAuthenticationFailureHandler(authFailureHandler); jwtAuthenticationFilter.setFilterProcessesUrl("/auth/login"); - //카카오 로그인 URL 설정 JwtKakaoAuthenticationFilter jwtKakaoAuthenticationFilter = new JwtKakaoAuthenticationFilter(http, rsaSecuritySigner, rsaKey, memberService, refreshTokenService); jwtKakaoAuthenticationFilter.setAuthenticationFailureHandler(authFailureHandler); jwtKakaoAuthenticationFilter.setFilterProcessesUrl("/auth/kakao"); - //인가 필터 등록 필터 http.addFilter(jwtAuthenticationFilter).addFilter(jwtKakaoAuthenticationFilter) .addFilterBefore(new JwtAuthorizationRsaFilter(rsaKey), UsernamePasswordAuthenticationFilter.class); diff --git a/src/main/java/com/umc/refit/web/config/ThymeleafConfig.java b/src/main/java/com/umc/refit/web/config/ThymeleafConfig.java new file mode 100644 index 0000000..d6206ec --- /dev/null +++ b/src/main/java/com/umc/refit/web/config/ThymeleafConfig.java @@ -0,0 +1,14 @@ +package com.umc.refit.web.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.thymeleaf.spring5.SpringTemplateEngine; + +@Configuration +public class ThymeleafConfig { + @Bean + public SpringTemplateEngine templateEngine() { + SpringTemplateEngine templateEngine = new SpringTemplateEngine(); + return templateEngine; + } +} diff --git a/src/main/java/com/umc/refit/web/controller/BlockController.java b/src/main/java/com/umc/refit/web/controller/BlockController.java index 8cc87dc..28cde61 100644 --- a/src/main/java/com/umc/refit/web/controller/BlockController.java +++ b/src/main/java/com/umc/refit/web/controller/BlockController.java @@ -11,7 +11,7 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; @RestController @RequestMapping("/refit/block") diff --git a/src/main/java/com/umc/refit/web/controller/ClotheController.java b/src/main/java/com/umc/refit/web/controller/ClotheController.java index 155ad82..60aa54b 100644 --- a/src/main/java/com/umc/refit/web/controller/ClotheController.java +++ b/src/main/java/com/umc/refit/web/controller/ClotheController.java @@ -12,8 +12,8 @@ import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; -import javax.servlet.http.HttpServletRequest; -import javax.validation.Valid; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.validation.Valid; import java.util.List; @Slf4j diff --git a/src/main/java/com/umc/refit/web/controller/CommunityController.java b/src/main/java/com/umc/refit/web/controller/CommunityController.java index 6ff8996..92c95be 100644 --- a/src/main/java/com/umc/refit/web/controller/CommunityController.java +++ b/src/main/java/com/umc/refit/web/controller/CommunityController.java @@ -12,7 +12,7 @@ import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import java.io.IOException; import java.util.List; diff --git a/src/main/java/com/umc/refit/web/controller/MemberController.java b/src/main/java/com/umc/refit/web/controller/MemberController.java index e612cf0..b94e607 100644 --- a/src/main/java/com/umc/refit/web/controller/MemberController.java +++ b/src/main/java/com/umc/refit/web/controller/MemberController.java @@ -1,6 +1,5 @@ package com.umc.refit.web.controller; -import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.nimbusds.jose.JOSEException; import com.nimbusds.jose.jwk.JWK; @@ -16,15 +15,15 @@ import com.umc.refit.web.service.RefreshTokenService; import com.umc.refit.web.signature.SecuritySigner; +import jakarta.mail.MessagingException; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.ResponseEntity; import org.springframework.security.core.Authentication; import org.springframework.security.core.userdetails.User; import org.springframework.web.bind.annotation.*; -import javax.mail.MessagingException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Optional; diff --git a/src/main/java/com/umc/refit/web/controller/MypageController.java b/src/main/java/com/umc/refit/web/controller/MypageController.java index b58fb5c..48b0af3 100644 --- a/src/main/java/com/umc/refit/web/controller/MypageController.java +++ b/src/main/java/com/umc/refit/web/controller/MypageController.java @@ -20,8 +20,8 @@ import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; -import javax.servlet.http.HttpServletRequest; -import javax.validation.Valid; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.validation.Valid; import java.util.List; import java.util.Optional; diff --git a/src/main/java/com/umc/refit/web/controller/OauthController.java b/src/main/java/com/umc/refit/web/controller/OauthController.java index eed2591..c73187f 100644 --- a/src/main/java/com/umc/refit/web/controller/OauthController.java +++ b/src/main/java/com/umc/refit/web/controller/OauthController.java @@ -16,7 +16,7 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.util.Optional; diff --git a/src/main/java/com/umc/refit/web/controller/ReportMemController.java b/src/main/java/com/umc/refit/web/controller/ReportMemController.java index bed954c..ea6a0f2 100644 --- a/src/main/java/com/umc/refit/web/controller/ReportMemController.java +++ b/src/main/java/com/umc/refit/web/controller/ReportMemController.java @@ -9,8 +9,8 @@ import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.*; -import javax.servlet.http.HttpServletRequest; -import javax.validation.Valid; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.validation.Valid; @RestController @RequestMapping("/refit/report") diff --git a/src/main/java/com/umc/refit/web/controller/TradeController.java b/src/main/java/com/umc/refit/web/controller/TradeController.java index 4f3bd82..e4ba620 100644 --- a/src/main/java/com/umc/refit/web/controller/TradeController.java +++ b/src/main/java/com/umc/refit/web/controller/TradeController.java @@ -9,7 +9,7 @@ import org.springframework.security.core.Authentication; import org.springframework.web.bind.annotation.*; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; @RestController @RequestMapping("/refit/trade") diff --git a/src/main/java/com/umc/refit/web/filter/authentication/JwtAuthenticationFilter.java b/src/main/java/com/umc/refit/web/filter/authentication/JwtAuthenticationFilter.java index b7bfbdd..b2eb379 100644 --- a/src/main/java/com/umc/refit/web/filter/authentication/JwtAuthenticationFilter.java +++ b/src/main/java/com/umc/refit/web/filter/authentication/JwtAuthenticationFilter.java @@ -36,7 +36,6 @@ public class JwtAuthenticationFilter extends UsernamePasswordAuthenticationFilte private final MemberService memberService; private final RefreshTokenService refreshTokenService; - /*일반 로그인 인증 시작 메서드*/ @Override public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { @@ -47,14 +46,12 @@ public Authentication attemptAuthentication(HttpServletRequest request, HttpServ Optional findMember = memberService.findMemberByLoginId(loginId); - //이미 카카오 계정이 있는 경우, 예외 발생 if (findMember.isPresent()) { if (!(findMember.get().getSocialType() == null)) { throw new LoginException(KAKAO_MEMBER_EXIST, KAKAO_MEMBER_EXIST.getCode(), KAKAO_MEMBER_EXIST.getErrorMessage()); } - //fcm 토큰 저장 Member member = findMember.get(); member.setFcm(fcm); memberService.updateFcm(member); @@ -66,7 +63,6 @@ public Authentication attemptAuthentication(HttpServletRequest request, HttpServ return authentication; } - /*일반 로그인 인증 성공시 토큰 발행하는 메소드*/ @Override protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws ServletException, IOException { diff --git a/src/main/java/com/umc/refit/web/filter/authentication/JwtKakaoAuthenticationFilter.java b/src/main/java/com/umc/refit/web/filter/authentication/JwtKakaoAuthenticationFilter.java index bf486a6..80e642c 100644 --- a/src/main/java/com/umc/refit/web/filter/authentication/JwtKakaoAuthenticationFilter.java +++ b/src/main/java/com/umc/refit/web/filter/authentication/JwtKakaoAuthenticationFilter.java @@ -65,7 +65,6 @@ public Authentication attemptAuthentication(HttpServletRequest request, HttpServ BASIC_MEMBER_EXIST.getCode(), BASIC_MEMBER_EXIST.getErrorMessage()); } - //fcm 토큰 저장 Member member = findMember.get(); member.setFcm(fcm); memberService.updateFcm(member); @@ -93,7 +92,6 @@ public Authentication attemptAuthentication(HttpServletRequest request, HttpServ return authentication; } - /*카카오 로그인 인증 성공시 토큰 발행하는 메소드*/ @Override protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws ServletException, IOException { User user = (User) authResult.getPrincipal(); diff --git a/src/main/java/com/umc/refit/web/filter/authorization/JwtAuthorizationRsaFilter.java b/src/main/java/com/umc/refit/web/filter/authorization/JwtAuthorizationRsaFilter.java index ce5dd82..f7940f8 100644 --- a/src/main/java/com/umc/refit/web/filter/authorization/JwtAuthorizationRsaFilter.java +++ b/src/main/java/com/umc/refit/web/filter/authorization/JwtAuthorizationRsaFilter.java @@ -23,7 +23,6 @@ import static com.umc.refit.exception.ExceptionType.*; -/*Bearer 토큰을 RSA 알고리즘에 의해 검증하며 검증 성공시 인증 및 인가를 처리하는 필터*/ public class JwtAuthorizationRsaFilter extends OncePerRequestFilter { private RSAKey jwk; @@ -32,23 +31,21 @@ public JwtAuthorizationRsaFilter(RSAKey rsaKey) { this.jwk = rsaKey; } - /*인가 처리를 거치지 않는 URL 설정 필터*/ @Override protected boolean shouldNotFilter(HttpServletRequest request) { String path = request.getServletPath(); request.getMethod(); AntPathMatcher pathMatcher = new AntPathMatcher(); - return (pathMatcher.match("/auth/join", path) //일반 회원 가입 - || pathMatcher.match("/auth/kakao", path) //카카오 로그인 - || pathMatcher.match("/auth/email", path) //이메일 인증 - || pathMatcher.match("/auth/find/id", path) //아이디 찾기 - || pathMatcher.match("/auth/reset/password", path) //패스워드 찾기 - || pathMatcher.match("/auth/login", path) //일반 로그인 + return (pathMatcher.match("/auth/join", path) + || pathMatcher.match("/auth/kakao", path) + || pathMatcher.match("/auth/email", path) + || pathMatcher.match("/auth/find/id", path) + || pathMatcher.match("/auth/reset/password", path) + || pathMatcher.match("/auth/login", path) || pathMatcher.match("/*.html", path) || pathMatcher.match("/oauth2/fcm", path) || pathMatcher.match("/oauth2/image", path) || pathMatcher.match("/auth/join/name", path) -// || pathMatcher.match("/**", path) //API 테스트를 위해 모든 로직에 대해 인가 제외 ); } diff --git a/src/main/java/com/umc/refit/web/repository/CommunityRepositoryImpl.java b/src/main/java/com/umc/refit/web/repository/CommunityRepositoryImpl.java index a3aa1ed..38ce3be 100644 --- a/src/main/java/com/umc/refit/web/repository/CommunityRepositoryImpl.java +++ b/src/main/java/com/umc/refit/web/repository/CommunityRepositoryImpl.java @@ -5,9 +5,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; -import javax.persistence.EntityManager; +import jakarta.persistence.EntityManager; import java.util.List; - import static com.umc.refit.domain.entity.QPosts.posts; @Repository diff --git a/src/main/java/com/umc/refit/web/service/BlockService.java b/src/main/java/com/umc/refit/web/service/BlockService.java index e1780f1..6a5e453 100644 --- a/src/main/java/com/umc/refit/web/service/BlockService.java +++ b/src/main/java/com/umc/refit/web/service/BlockService.java @@ -9,7 +9,7 @@ import org.springframework.security.core.Authentication; import org.springframework.stereotype.Service; -import javax.transaction.Transactional; +import jakarta.transaction.Transactional; import java.util.List; import java.util.stream.Collectors; diff --git a/src/main/java/com/umc/refit/web/service/CmImgService.java b/src/main/java/com/umc/refit/web/service/CmImgService.java index e24823d..d6a1cc3 100644 --- a/src/main/java/com/umc/refit/web/service/CmImgService.java +++ b/src/main/java/com/umc/refit/web/service/CmImgService.java @@ -8,7 +8,7 @@ import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; -import javax.transaction.Transactional; +import jakarta.transaction.Transactional; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/com/umc/refit/web/service/CommunityService.java b/src/main/java/com/umc/refit/web/service/CommunityService.java index d32f896..7a4e3d6 100644 --- a/src/main/java/com/umc/refit/web/service/CommunityService.java +++ b/src/main/java/com/umc/refit/web/service/CommunityService.java @@ -14,7 +14,7 @@ import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; -import javax.transaction.Transactional; +import jakarta.transaction.Transactional; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; diff --git a/src/main/java/com/umc/refit/web/service/EmailService.java b/src/main/java/com/umc/refit/web/service/EmailService.java index 1d0e407..8c755dc 100644 --- a/src/main/java/com/umc/refit/web/service/EmailService.java +++ b/src/main/java/com/umc/refit/web/service/EmailService.java @@ -2,15 +2,13 @@ import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Value; -import org.springframework.mail.SimpleMailMessage; import org.springframework.mail.javamail.JavaMailSender; -import org.springframework.mail.javamail.MimeMessageHelper; import org.springframework.stereotype.Service; import org.thymeleaf.context.Context; import org.thymeleaf.spring5.SpringTemplateEngine; -import javax.mail.MessagingException; -import javax.mail.internet.MimeMessage; +import jakarta.mail.MessagingException; +import jakarta.mail.internet.MimeMessage; import java.security.SecureRandom; import java.util.Random; @@ -18,7 +16,6 @@ @RequiredArgsConstructor public class EmailService { - private final JavaMailSender mailSender; private final SpringTemplateEngine templateEngine; @@ -59,7 +56,7 @@ public MimeMessage joinEmailForm(String email) throws MessagingException { String title = "[RE-FIT] 회원가입 인증번호 안내 이메일 입니다."; MimeMessage message = mailSender.createMimeMessage(); - message.addRecipients(MimeMessage.RecipientType.TO, email); //보낼 이메일 설정 + message.addRecipients(MimeMessage.RecipientType.TO, email); message.setSubject(title); message.setFrom(from); diff --git a/src/main/java/com/umc/refit/web/service/ReportMemService.java b/src/main/java/com/umc/refit/web/service/ReportMemService.java index 588a678..b47692c 100644 --- a/src/main/java/com/umc/refit/web/service/ReportMemService.java +++ b/src/main/java/com/umc/refit/web/service/ReportMemService.java @@ -9,7 +9,7 @@ import org.springframework.security.core.Authentication; import org.springframework.stereotype.Service; -import javax.transaction.Transactional; +import jakarta.transaction.Transactional; import static com.umc.refit.exception.ExceptionType.*; diff --git a/src/main/java/com/umc/refit/web/service/S3UploadService.java b/src/main/java/com/umc/refit/web/service/S3UploadService.java index f66e65c..e39ab2a 100644 --- a/src/main/java/com/umc/refit/web/service/S3UploadService.java +++ b/src/main/java/com/umc/refit/web/service/S3UploadService.java @@ -12,7 +12,7 @@ import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; -import javax.transaction.Transactional; +import jakarta.transaction.Transactional; import java.io.IOException; import java.util.UUID; @@ -23,10 +23,8 @@ @Transactional public class S3UploadService { - private final AmazonS3Client amazonS3Client; private final AmazonS3 s3; - /*멀티파트파일을 지정한 s3 버킷의 폴더에 저장 * ImageDto 객체에 key name, url 넣어서 반환 * */ @@ -43,7 +41,7 @@ public ImageDto uploadFile(MultipartFile multipartFile, String bucketName, Strin PutObjectRequest request = new PutObjectRequest(bucketName, keyName, multipartFile.getInputStream(), metadata).withCannedAcl(CannedAccessControlList.PublicRead); s3.putObject(request); - String uploadImageUrl = amazonS3Client.getUrl(bucketName, keyName).toString(); + String uploadImageUrl = s3.getUrl(bucketName, keyName).toString(); ImageDto imageDto = new ImageDto(keyName, uploadImageUrl); return imageDto; diff --git a/src/main/java/com/umc/refit/web/service/ScrapService.java b/src/main/java/com/umc/refit/web/service/ScrapService.java index aae6a08..c7de070 100644 --- a/src/main/java/com/umc/refit/web/service/ScrapService.java +++ b/src/main/java/com/umc/refit/web/service/ScrapService.java @@ -11,7 +11,7 @@ import org.springframework.security.core.Authentication; import org.springframework.stereotype.Service; -import javax.transaction.Transactional; +import jakarta.transaction.Transactional; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 3049bb0..ab9cb59 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -21,7 +21,7 @@ spring: properties: hibernate: - dialect: org.hibernate.dialect.MySQL5Dialect + dialect: org.hibernate.dialect.MySQL8Dialect format_sql: true default_batch_fetch_size: 100 From bb72564592f7a4653b25e840494ea513a52f7503 Mon Sep 17 00:00:00 2001 From: Ji Seungmin Date: Mon, 18 Dec 2023 18:25:47 +0900 Subject: [PATCH 04/13] =?UTF-8?q?fix:=20[BE]=20Spring=20Security=20Config?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../umc/refit/web/config/SpringSecurityConfig.java | 14 ++++++++++---- .../authorization/JwtAuthorizationRsaFilter.java | 11 +---------- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/umc/refit/web/config/SpringSecurityConfig.java b/src/main/java/com/umc/refit/web/config/SpringSecurityConfig.java index f27f58b..8a77087 100644 --- a/src/main/java/com/umc/refit/web/config/SpringSecurityConfig.java +++ b/src/main/java/com/umc/refit/web/config/SpringSecurityConfig.java @@ -11,8 +11,8 @@ import com.umc.refit.web.service.RefreshTokenService; import com.umc.refit.web.signature.RSASecuritySigner; import lombok.RequiredArgsConstructor; -import org.springframework.beans.factory.annotation.Autowired; 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; @@ -20,6 +20,7 @@ import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; @EnableWebSecurity +@Configuration @RequiredArgsConstructor public class SpringSecurityConfig { @@ -27,15 +28,15 @@ public class SpringSecurityConfig { private final RSAKey rsaKey; private final CustomUserDetailsService userDetailsService; private final CustomAuthenticationFailureHandler authFailureHandler; + private final CustomAuthenticationEntryPoint authenticationEntryPoint; private final MemberService memberService; private final RefreshTokenService refreshTokenService; - private final CustomAuthenticationEntryPoint authenticationEntryPoint; private String[] permitAllUrlPatterns() { return new String[] { "/auth/logout", "/auth/join", "/auth/email", "/auth/find/id", "/auth/reset/password", "/static/**", "/*.html", "/oauth2/fcm", - "/oauth2/image", "/auth/join/name" + "/oauth2/image", "/auth/join/name", }; } @@ -45,7 +46,12 @@ SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http.authorizeHttpRequests((requests) -> requests.requestMatchers(permitAllUrlPatterns()).permitAll() .anyRequest().authenticated()) - .exceptionHandling(error -> error.authenticationEntryPoint(authenticationEntryPoint)); + .exceptionHandling(handler -> handler.authenticationEntryPoint(authenticationEntryPoint)); + + http.csrf(csrf -> csrf.disable()); + http.sessionManagement(sessionManagement -> + sessionManagement.sessionCreationPolicy(SessionCreationPolicy.STATELESS) + ); http.userDetailsService(userDetailsService); diff --git a/src/main/java/com/umc/refit/web/filter/authorization/JwtAuthorizationRsaFilter.java b/src/main/java/com/umc/refit/web/filter/authorization/JwtAuthorizationRsaFilter.java index f7940f8..a32505f 100644 --- a/src/main/java/com/umc/refit/web/filter/authorization/JwtAuthorizationRsaFilter.java +++ b/src/main/java/com/umc/refit/web/filter/authorization/JwtAuthorizationRsaFilter.java @@ -54,21 +54,16 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse ExceptionType errorType = null; - /*토큰 헤더 검증*/ if (tokenResolve(request, response, chain)){ errorType = TOKEN_NOT_EXIST; } else { - //Bearer를 제거한 토큰 값만 추출(header + payload + signature) String token = getToken(request); SignedJWT signedJWT; try { - - //header와 payload와 signature 값이 속성으로 매핑됨 signedJWT = SignedJWT.parse(token); RSASSAVerifier jwsVerifier = new RSASSAVerifier(jwk.toRSAPublicKey()); - /*토큰 만료기간 검증*/ Date expirationTime = signedJWT.getJWTClaimsSet().getExpirationTime(); Date now = new Date(); if (now.after(expirationTime)) { @@ -81,7 +76,6 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse String username = signedJWT.getJWTClaimsSet().getClaim("id").toString(); List authority = (List) signedJWT.getJWTClaimsSet().getClaim("role"); - //사용자 정보를 만들어서 인증 객체 생성 후 Security Context에 보관 if (username != null) { UserDetails user = User.builder().username(username) .password(UUID.randomUUID().toString()) @@ -98,19 +92,16 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse errorType = TOKEN_INVALID; } } - /*토큰 예외 처리*/ if (errorType != null) { request.setAttribute("exception", errorType); } - chain.doFilter(request, response); //다음 필터로 넘어감 + chain.doFilter(request, response); } - /*Authorization 헤더로 넘어온 엑세스 토큰 값 추출*/ protected String getToken(HttpServletRequest request) { return request.getHeader("Authorization").replace("Bearer ", ""); } - /*헤더 유효성 검사*/ protected boolean tokenResolve(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException { String header = request.getHeader("Authorization"); return header == null || !header.startsWith("Bearer "); From 6d2144494782e97b2ef58d9029eed2923c8f6c0a Mon Sep 17 00:00:00 2001 From: Ji Seungmin Date: Mon, 18 Dec 2023 18:31:42 +0900 Subject: [PATCH 05/13] =?UTF-8?q?refactor:=20CustomAuthenticationFailureHa?= =?UTF-8?q?ndler=EC=97=90=20Early=20Return=20=ED=8C=A8=ED=84=B4=20?= =?UTF-8?q?=EC=A0=81=EC=9A=A9=ED=95=98=EC=97=AC=20=EB=A6=AC=ED=8C=A9?= =?UTF-8?q?=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../umc/refit/exception/ExceptionType.java | 2 +- .../CustomAuthenticationFailureHandler.java | 30 +++++++++---------- 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/src/main/java/com/umc/refit/exception/ExceptionType.java b/src/main/java/com/umc/refit/exception/ExceptionType.java index f46cc49..1276ae9 100644 --- a/src/main/java/com/umc/refit/exception/ExceptionType.java +++ b/src/main/java/com/umc/refit/exception/ExceptionType.java @@ -40,7 +40,7 @@ public enum ExceptionType { //로그인 예외 LOGIN_FAILED(BAD_REQUEST, 10103, "존재하지 않는 계정입니다."), - LOGIN_FAILED_ALL(BAD_REQUEST, 10104, "알 수 없는 이유로 로그인 할 수 없습니다."), + LOGIN_FAILED_UNKNOWN(BAD_REQUEST, 10104, "알 수 없는 이유로 로그인 할 수 없습니다."), KAKAO_MEMBER_EXIST(BAD_REQUEST, 10105, "카카오 로그인 계정이 존재합니다."), BASIC_MEMBER_EXIST(BAD_REQUEST, 10106, "일반 로그인 계정이 존재합니다."), diff --git a/src/main/java/com/umc/refit/web/filter/exception/CustomAuthenticationFailureHandler.java b/src/main/java/com/umc/refit/web/filter/exception/CustomAuthenticationFailureHandler.java index ad676ef..a71509b 100644 --- a/src/main/java/com/umc/refit/web/filter/exception/CustomAuthenticationFailureHandler.java +++ b/src/main/java/com/umc/refit/web/filter/exception/CustomAuthenticationFailureHandler.java @@ -14,8 +14,7 @@ import java.io.IOException; import java.util.HashMap; -import static com.umc.refit.exception.ExceptionType.LOGIN_FAILED; -import static com.umc.refit.exception.ExceptionType.LOGIN_FAILED_ALL; +import static com.umc.refit.exception.ExceptionType.*; @Component public class CustomAuthenticationFailureHandler implements AuthenticationFailureHandler { @@ -23,24 +22,23 @@ public class CustomAuthenticationFailureHandler implements AuthenticationFailure @Override public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException { + if (exception instanceof UsernameNotFoundException || exception instanceof BadCredentialsException) { + sendErrorResponse(response, LOGIN_FAILED.getErrorMessage(), LOGIN_FAILED.getCode()); + return; + } + + if (exception instanceof LoginException) { + sendErrorResponse(response, ((LoginException) exception).getErrorMessage(), ((LoginException) exception).getCode()); + return; + } + sendErrorResponse(response, LOGIN_FAILED_UNKNOWN.getErrorMessage(), LOGIN_FAILED_UNKNOWN.getCode()); + } + + private void sendErrorResponse(HttpServletResponse response, String errorMessage, int code) throws IOException { response.setStatus(HttpStatus.BAD_REQUEST.value()); response.setContentType("application/json;charset=UTF-8"); - String errorMessage; - int code; - - if ((exception instanceof UsernameNotFoundException) || (exception instanceof BadCredentialsException)){ - errorMessage = LOGIN_FAILED.getErrorMessage(); - code = LOGIN_FAILED.getCode(); - } else if (exception instanceof LoginException) { - errorMessage = ((LoginException) exception).getErrorMessage(); - code = ((LoginException) exception).getCode(); - } else { - errorMessage = LOGIN_FAILED_ALL.getErrorMessage(); - code = LOGIN_FAILED_ALL.getCode(); - } - ObjectMapper mapper = new ObjectMapper(); HashMap errorResponse = new HashMap<>(); errorResponse.put("errorMessage", errorMessage); From 027704cd9c6b9a3858989370eb0a0590d46de29b Mon Sep 17 00:00:00 2001 From: Ji Seungmin Date: Tue, 19 Dec 2023 13:43:31 +0900 Subject: [PATCH 06/13] =?UTF-8?q?fix:=20JWT=20=ED=86=A0=ED=81=B0=20?= =?UTF-8?q?=EB=B0=9C=EA=B8=89=20=EB=B0=A9=EC=8B=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 6 +++ .../umc/refit/web/config/SignatureConfig.java | 9 ++++ .../web/config/SpringSecurityConfig.java | 15 ++++-- .../JwtAuthenticationFilter.java | 47 ++++++++--------- .../JwtAuthorizationRsaFilter.java | 52 +++++++++---------- .../umc/refit/web/signature/JWTSigner.java | 36 +++++++++++++ 6 files changed, 109 insertions(+), 56 deletions(-) create mode 100644 src/main/java/com/umc/refit/web/signature/JWTSigner.java diff --git a/build.gradle b/build.gradle index 8e7611e..2529c16 100644 --- a/build.gradle +++ b/build.gradle @@ -56,6 +56,12 @@ dependencies { //AWS S3 implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE' + //JWT + implementation 'io.jsonwebtoken:jjwt-api:0.11.5' + runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5' + runtimeOnly 'io.jsonwebtoken:jjwt-orgjson:0.11.5' + implementation 'org.json:json:20210307' + //querydsl 추가 implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta' annotationProcessor "com.querydsl:querydsl-apt:5.0.0:jakarta" diff --git a/src/main/java/com/umc/refit/web/config/SignatureConfig.java b/src/main/java/com/umc/refit/web/config/SignatureConfig.java index 1a0fac4..5c674a5 100644 --- a/src/main/java/com/umc/refit/web/config/SignatureConfig.java +++ b/src/main/java/com/umc/refit/web/config/SignatureConfig.java @@ -5,11 +5,15 @@ import com.nimbusds.jose.jwk.RSAKey; import com.nimbusds.jose.jwk.gen.RSAKeyGenerator; import com.umc.refit.web.signature.RSASecuritySigner; +import io.jsonwebtoken.SignatureAlgorithm; +import io.jsonwebtoken.security.Keys; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; +import java.security.Key; + @Configuration public class SignatureConfig { @@ -30,4 +34,9 @@ public RSAKey rsaKey512() throws JOSEException { public PasswordEncoder passwordEncoder(){ return new BCryptPasswordEncoder(); } + + @Bean + public Key jwtSigningKey() { + return Keys.secretKeyFor(SignatureAlgorithm.HS256); + } } \ No newline at end of file diff --git a/src/main/java/com/umc/refit/web/config/SpringSecurityConfig.java b/src/main/java/com/umc/refit/web/config/SpringSecurityConfig.java index 8a77087..2405bd1 100644 --- a/src/main/java/com/umc/refit/web/config/SpringSecurityConfig.java +++ b/src/main/java/com/umc/refit/web/config/SpringSecurityConfig.java @@ -9,16 +9,23 @@ import com.umc.refit.web.filter.exception.CustomAuthenticationFailureHandler; import com.umc.refit.web.service.MemberService; import com.umc.refit.web.service.RefreshTokenService; +import com.umc.refit.web.signature.JWTSigner; import com.umc.refit.web.signature.RSASecuritySigner; +import io.jsonwebtoken.SignatureAlgorithm; +import io.jsonwebtoken.security.Keys; import lombok.RequiredArgsConstructor; 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.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; +import java.security.Key; + @EnableWebSecurity @Configuration @RequiredArgsConstructor @@ -31,6 +38,8 @@ public class SpringSecurityConfig { private final CustomAuthenticationEntryPoint authenticationEntryPoint; private final MemberService memberService; private final RefreshTokenService refreshTokenService; + private final JWTSigner jwtSigner; + private final Key key; private String[] permitAllUrlPatterns() { return new String[] { @@ -45,7 +54,7 @@ SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http.authorizeHttpRequests((requests) -> requests.requestMatchers(permitAllUrlPatterns()).permitAll() - .anyRequest().authenticated()) + .anyRequest().authenticated()) .exceptionHandling(handler -> handler.authenticationEntryPoint(authenticationEntryPoint)); http.csrf(csrf -> csrf.disable()); @@ -56,7 +65,7 @@ SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http.userDetailsService(userDetailsService); JwtAuthenticationFilter jwtAuthenticationFilter = - new JwtAuthenticationFilter(http, rsaSecuritySigner, rsaKey, memberService, refreshTokenService); + new JwtAuthenticationFilter(http, jwtSigner, memberService, refreshTokenService); jwtAuthenticationFilter.setAuthenticationFailureHandler(authFailureHandler); jwtAuthenticationFilter.setFilterProcessesUrl("/auth/login"); @@ -66,7 +75,7 @@ SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { jwtKakaoAuthenticationFilter.setFilterProcessesUrl("/auth/kakao"); http.addFilter(jwtAuthenticationFilter).addFilter(jwtKakaoAuthenticationFilter) - .addFilterBefore(new JwtAuthorizationRsaFilter(rsaKey), UsernamePasswordAuthenticationFilter.class); + .addFilterBefore(new JwtAuthorizationRsaFilter(key), UsernamePasswordAuthenticationFilter.class); return http.build(); } diff --git a/src/main/java/com/umc/refit/web/filter/authentication/JwtAuthenticationFilter.java b/src/main/java/com/umc/refit/web/filter/authentication/JwtAuthenticationFilter.java index b2eb379..c09095a 100644 --- a/src/main/java/com/umc/refit/web/filter/authentication/JwtAuthenticationFilter.java +++ b/src/main/java/com/umc/refit/web/filter/authentication/JwtAuthenticationFilter.java @@ -8,6 +8,7 @@ import com.umc.refit.exception.member.LoginException; import com.umc.refit.web.service.MemberService; import com.umc.refit.web.service.RefreshTokenService; +import com.umc.refit.web.signature.JWTSigner; import com.umc.refit.web.signature.SecuritySigner; import jakarta.servlet.FilterChain; import jakarta.servlet.ServletException; @@ -31,8 +32,9 @@ public class JwtAuthenticationFilter extends UsernamePasswordAuthenticationFilter { private final HttpSecurity httpSecurity; - private final SecuritySigner securitySigner; - private final JWK jwk; +// private final SecuritySigner securitySigner; + private final JWTSigner securitySigner; +// private final JWK jwk; private final MemberService memberService; private final RefreshTokenService refreshTokenService; @@ -64,29 +66,24 @@ public Authentication attemptAuthentication(HttpServletRequest request, HttpServ } @Override - protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws - ServletException, IOException { + protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, + FilterChain chain, Authentication authResult) throws IOException { User user = (User) authResult.getPrincipal(); - try { - //엑세스 토큰 및 리프레쉬 토큰 발행 - String accessToken = securitySigner.getJwtToken(user, jwk, 216000000); - String refreshToken = securitySigner.getJwtToken(user, jwk, 216000000); - - //리프레쉬 토큰 저장 - refreshTokenService.saveRefreshToken(user.getUsername(), refreshToken); - - //엑세스 토큰 헤더를 통해 전달 - response.addHeader("Authorization", "Bearer " + accessToken); //발행받은 토큰을 response 헤더에 담아 응답 - - //리프레쉬 토큰 바디에 담아 전달 - ResLoginDto resEmailDto = new ResLoginDto(refreshToken); - response.setContentType("application/json"); - ObjectMapper objectMapper = new ObjectMapper(); - String jsonString = objectMapper.writeValueAsString(resEmailDto); - response.getWriter().write(jsonString); - - } catch (JOSEException e) { - e.printStackTrace(); - } + //엑세스 토큰 및 리프레쉬 토큰 발행 + String accessToken = securitySigner.getJwtToken(user, 216000000); + String refreshToken = securitySigner.getJwtToken(user, 216000000); + + //리프레쉬 토큰 저장 + refreshTokenService.saveRefreshToken(user.getUsername(), refreshToken); + + //엑세스 토큰 헤더를 통해 전달 + response.addHeader("Authorization", "Bearer " + accessToken); //발행받은 토큰을 response 헤더에 담아 응답 + + //리프레쉬 토큰 바디에 담아 전달 + ResLoginDto resEmailDto = new ResLoginDto(refreshToken); + response.setContentType("application/json"); + ObjectMapper objectMapper = new ObjectMapper(); + String jsonString = objectMapper.writeValueAsString(resEmailDto); + response.getWriter().write(jsonString); } } diff --git a/src/main/java/com/umc/refit/web/filter/authorization/JwtAuthorizationRsaFilter.java b/src/main/java/com/umc/refit/web/filter/authorization/JwtAuthorizationRsaFilter.java index a32505f..b7dfc2f 100644 --- a/src/main/java/com/umc/refit/web/filter/authorization/JwtAuthorizationRsaFilter.java +++ b/src/main/java/com/umc/refit/web/filter/authorization/JwtAuthorizationRsaFilter.java @@ -1,13 +1,15 @@ package com.umc.refit.web.filter.authorization; import com.nimbusds.jose.crypto.RSASSAVerifier; -import com.nimbusds.jose.jwk.RSAKey; import com.nimbusds.jwt.SignedJWT; import com.umc.refit.exception.ExceptionType; +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jwts; import jakarta.servlet.FilterChain; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; +import lombok.RequiredArgsConstructor; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; @@ -17,19 +19,17 @@ import org.springframework.web.filter.OncePerRequestFilter; import java.io.IOException; +import java.security.Key; import java.util.Date; import java.util.List; import java.util.UUID; import static com.umc.refit.exception.ExceptionType.*; +@RequiredArgsConstructor public class JwtAuthorizationRsaFilter extends OncePerRequestFilter { - private RSAKey jwk; - - public JwtAuthorizationRsaFilter(RSAKey rsaKey) { - this.jwk = rsaKey; - } + private final Key key; @Override protected boolean shouldNotFilter(HttpServletRequest request) { @@ -57,33 +57,29 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse if (tokenResolve(request, response, chain)){ errorType = TOKEN_NOT_EXIST; } else { - - String token = getToken(request); - SignedJWT signedJWT; try { - signedJWT = SignedJWT.parse(token); - RSASSAVerifier jwsVerifier = new RSASSAVerifier(jwk.toRSAPublicKey()); - - Date expirationTime = signedJWT.getJWTClaimsSet().getExpirationTime(); + String token = getToken(request); + Claims claims = Jwts.parserBuilder() + .setSigningKey(key) + .build() + .parseClaimsJws(token) + .getBody(); + + Date expirationTime = claims.getExpiration(); Date now = new Date(); if (now.after(expirationTime)) { errorType = TOKEN_EXPIRED; } else { - - boolean verify = signedJWT.verify(jwsVerifier); - - if (verify) { - String username = signedJWT.getJWTClaimsSet().getClaim("id").toString(); - List authority = (List) signedJWT.getJWTClaimsSet().getClaim("role"); - - if (username != null) { - UserDetails user = User.builder().username(username) - .password(UUID.randomUUID().toString()) - .authorities(authority.get(0)) - .build(); - Authentication authentication = new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities()); - SecurityContextHolder.getContext().setAuthentication(authentication); - } + String username = claims.getSubject(); + List authority = (List) claims.get("role"); + + if (username != null) { + UserDetails user = User.builder().username(username) + .password(UUID.randomUUID().toString()) + .authorities(authority.get(0)) + .build(); + Authentication authentication = new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities()); + SecurityContextHolder.getContext().setAuthentication(authentication); } else { errorType = TOKEN_INVALID; } diff --git a/src/main/java/com/umc/refit/web/signature/JWTSigner.java b/src/main/java/com/umc/refit/web/signature/JWTSigner.java new file mode 100644 index 0000000..1fd8515 --- /dev/null +++ b/src/main/java/com/umc/refit/web/signature/JWTSigner.java @@ -0,0 +1,36 @@ +package com.umc.refit.web.signature; + +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.SignatureAlgorithm; +import io.jsonwebtoken.security.Keys; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.stereotype.Component; + +import java.security.Key; +import java.util.Date; +import java.util.List; +import java.util.stream.Collectors; + +@Component +@RequiredArgsConstructor +public class JWTSigner { + + @Value("${token.issuer}") + private String issuer; + private final Key key; + + public String getJwtToken(User user, Integer time) { + List authority = user.getAuthorities().stream().map(auth -> auth.getAuthority()).collect(Collectors.toList()); + + return Jwts.builder() + .setSubject(user.getUsername()) + .setIssuer(issuer) + .setExpiration(new Date(new Date().getTime() + time)) + .claim("role", authority) + .signWith(key, SignatureAlgorithm.HS256) + .compact(); + } +} From 8e854894c27d8f8e8c4b96c432470191ff96c04b Mon Sep 17 00:00:00 2001 From: Ji Seungmin Date: Tue, 19 Dec 2023 14:06:24 +0900 Subject: [PATCH 07/13] =?UTF-8?q?refactor:=20=EC=9D=B8=EA=B0=80=20?= =?UTF-8?q?=ED=95=84=ED=84=B0=20=EA=B5=AC=EC=A1=B0=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../JwtAuthorizationRsaFilter.java | 87 +++++++++++-------- 1 file changed, 49 insertions(+), 38 deletions(-) diff --git a/src/main/java/com/umc/refit/web/filter/authorization/JwtAuthorizationRsaFilter.java b/src/main/java/com/umc/refit/web/filter/authorization/JwtAuthorizationRsaFilter.java index b7dfc2f..35e3a5e 100644 --- a/src/main/java/com/umc/refit/web/filter/authorization/JwtAuthorizationRsaFilter.java +++ b/src/main/java/com/umc/refit/web/filter/authorization/JwtAuthorizationRsaFilter.java @@ -51,54 +51,65 @@ protected boolean shouldNotFilter(HttpServletRequest request) { @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException { + try { + if (tokenResolve(request)) { + setException(request, TOKEN_NOT_EXIST, chain, response); + return; + } - ExceptionType errorType = null; - - if (tokenResolve(request, response, chain)){ - errorType = TOKEN_NOT_EXIST; - } else { - try { - String token = getToken(request); - Claims claims = Jwts.parserBuilder() - .setSigningKey(key) - .build() - .parseClaimsJws(token) - .getBody(); - - Date expirationTime = claims.getExpiration(); - Date now = new Date(); - if (now.after(expirationTime)) { - errorType = TOKEN_EXPIRED; - } else { - String username = claims.getSubject(); - List authority = (List) claims.get("role"); - - if (username != null) { - UserDetails user = User.builder().username(username) - .password(UUID.randomUUID().toString()) - .authorities(authority.get(0)) - .build(); - Authentication authentication = new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities()); - SecurityContextHolder.getContext().setAuthentication(authentication); - } else { - errorType = TOKEN_INVALID; - } - } - } catch (Exception e) { - errorType = TOKEN_INVALID; + String token = getToken(request); + if (token == null) { + setException(request, TOKEN_INVALID, chain, response); + return; } + + Claims claims = Jwts.parserBuilder() + .setSigningKey(key) + .build() + .parseClaimsJws(token) + .getBody(); + + if (isTokenExpired(claims)) { + setException(request, TOKEN_EXPIRED, chain, response); + return; + } + + createAuthentication(claims); + } catch (Exception e) { + setException(request, TOKEN_INVALID, chain, response); + return; } - if (errorType != null) { - request.setAttribute("exception", errorType); - } + chain.doFilter(request, response); } + private void setException(HttpServletRequest request, ExceptionType errorType, FilterChain chain, HttpServletResponse response) throws IOException, ServletException { + request.setAttribute("exception", errorType); + chain.doFilter(request, response); + } + + private boolean isTokenExpired(Claims claims) { + return new Date().after(claims.getExpiration()); + } + + private void createAuthentication(Claims claims) { + String username = claims.getSubject(); + List authority = (List) claims.get("role"); + if (username != null && !authority.isEmpty()) { + UserDetails user = User.builder().username(username) + .password(UUID.randomUUID().toString()) + .authorities(authority.get(0)) + .build(); + Authentication authentication = new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities()); + SecurityContextHolder.getContext().setAuthentication(authentication); + } + } + protected String getToken(HttpServletRequest request) { return request.getHeader("Authorization").replace("Bearer ", ""); } - protected boolean tokenResolve(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException { + protected boolean tokenResolve(HttpServletRequest request) { String header = request.getHeader("Authorization"); return header == null || !header.startsWith("Bearer "); } From 8695960ff997637f65a0051b584d7cd6b6d6a150 Mon Sep 17 00:00:00 2001 From: Ji Seungmin Date: Tue, 19 Dec 2023 14:11:44 +0900 Subject: [PATCH 08/13] =?UTF-8?q?fix:=20OAUTH=20=EC=9D=B8=EC=A6=9D=20?= =?UTF-8?q?=ED=95=84=ED=84=B0=EB=8F=84=20=EC=88=98=EC=A0=95=ED=95=9C=20?= =?UTF-8?q?=ED=86=A0=ED=81=B0=20=EB=B0=9C=EA=B8=89=20=EB=B0=A9=EC=8B=9D?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../umc/refit/web/config/SignatureConfig.java | 14 ------ .../web/config/SpringSecurityConfig.java | 9 +--- .../web/controller/MemberController.java | 11 ++--- .../JwtAuthenticationFilter.java | 6 --- .../JwtKakaoAuthenticationFilter.java | 32 +++++-------- .../JwtAuthorizationRsaFilter.java | 2 - .../web/signature/RSASecuritySigner.java | 21 -------- .../refit/web/signature/SecuritySigner.java | 48 ------------------- 8 files changed, 16 insertions(+), 127 deletions(-) delete mode 100644 src/main/java/com/umc/refit/web/signature/RSASecuritySigner.java delete mode 100644 src/main/java/com/umc/refit/web/signature/SecuritySigner.java diff --git a/src/main/java/com/umc/refit/web/config/SignatureConfig.java b/src/main/java/com/umc/refit/web/config/SignatureConfig.java index 5c674a5..6038401 100644 --- a/src/main/java/com/umc/refit/web/config/SignatureConfig.java +++ b/src/main/java/com/umc/refit/web/config/SignatureConfig.java @@ -4,7 +4,6 @@ import com.nimbusds.jose.JWSAlgorithm; import com.nimbusds.jose.jwk.RSAKey; import com.nimbusds.jose.jwk.gen.RSAKeyGenerator; -import com.umc.refit.web.signature.RSASecuritySigner; import io.jsonwebtoken.SignatureAlgorithm; import io.jsonwebtoken.security.Keys; import org.springframework.context.annotation.Bean; @@ -17,19 +16,6 @@ @Configuration public class SignatureConfig { - @Bean - public RSASecuritySigner rsaSecuritySigner() { - return new RSASecuritySigner(); - } - - @Bean - public RSAKey rsaKey512() throws JOSEException { - return new RSAKeyGenerator(2048) - .keyID("rsaKey") - .algorithm(JWSAlgorithm.RS512) - .generate(); - } - @Bean public PasswordEncoder passwordEncoder(){ return new BCryptPasswordEncoder(); diff --git a/src/main/java/com/umc/refit/web/config/SpringSecurityConfig.java b/src/main/java/com/umc/refit/web/config/SpringSecurityConfig.java index 2405bd1..3c1da19 100644 --- a/src/main/java/com/umc/refit/web/config/SpringSecurityConfig.java +++ b/src/main/java/com/umc/refit/web/config/SpringSecurityConfig.java @@ -10,17 +10,12 @@ import com.umc.refit.web.service.MemberService; import com.umc.refit.web.service.RefreshTokenService; import com.umc.refit.web.signature.JWTSigner; -import com.umc.refit.web.signature.RSASecuritySigner; -import io.jsonwebtoken.SignatureAlgorithm; -import io.jsonwebtoken.security.Keys; import lombok.RequiredArgsConstructor; 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.bcrypt.BCryptPasswordEncoder; -import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; @@ -31,8 +26,6 @@ @RequiredArgsConstructor public class SpringSecurityConfig { - private final RSASecuritySigner rsaSecuritySigner; - private final RSAKey rsaKey; private final CustomUserDetailsService userDetailsService; private final CustomAuthenticationFailureHandler authFailureHandler; private final CustomAuthenticationEntryPoint authenticationEntryPoint; @@ -70,7 +63,7 @@ SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { jwtAuthenticationFilter.setFilterProcessesUrl("/auth/login"); JwtKakaoAuthenticationFilter jwtKakaoAuthenticationFilter = - new JwtKakaoAuthenticationFilter(http, rsaSecuritySigner, rsaKey, memberService, refreshTokenService); + new JwtKakaoAuthenticationFilter(http, jwtSigner, memberService, refreshTokenService); jwtKakaoAuthenticationFilter.setAuthenticationFailureHandler(authFailureHandler); jwtKakaoAuthenticationFilter.setFilterProcessesUrl("/auth/kakao"); diff --git a/src/main/java/com/umc/refit/web/controller/MemberController.java b/src/main/java/com/umc/refit/web/controller/MemberController.java index b94e607..8cc9c68 100644 --- a/src/main/java/com/umc/refit/web/controller/MemberController.java +++ b/src/main/java/com/umc/refit/web/controller/MemberController.java @@ -13,8 +13,8 @@ import com.umc.refit.web.service.MemberService; import com.umc.refit.web.service.RefreshTokenService; -import com.umc.refit.web.signature.SecuritySigner; +import com.umc.refit.web.signature.JWTSigner; import jakarta.mail.MessagingException; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Value; @@ -37,10 +37,7 @@ public class MemberController { private final EmailService emailService; private final MemberService memberService; private final RefreshTokenService refreshTokenService; - - //토큰 재발급 - private final SecuritySigner securitySigner; - private final JWK jwk; + private final JWTSigner securitySigner; @Value("${member.image}") private String imageUrl; @@ -179,8 +176,8 @@ public ResponseEntity token_reissue(Authentication authentication, HttpSer //토큰 재발급 코드 User user = (User) authentication.getPrincipal(); - String accessToken = securitySigner.getJwtToken(user, jwk, 216000000); - String refreshToken = securitySigner.getJwtToken(user, jwk, 216000000); + String accessToken = securitySigner.getJwtToken(user, 216000000); + String refreshToken = securitySigner.getJwtToken(user, 216000000); //리프레쉬 토큰 저장 refreshTokenService.saveRefreshToken(user.getUsername(), refreshToken); diff --git a/src/main/java/com/umc/refit/web/filter/authentication/JwtAuthenticationFilter.java b/src/main/java/com/umc/refit/web/filter/authentication/JwtAuthenticationFilter.java index c09095a..4edfc50 100644 --- a/src/main/java/com/umc/refit/web/filter/authentication/JwtAuthenticationFilter.java +++ b/src/main/java/com/umc/refit/web/filter/authentication/JwtAuthenticationFilter.java @@ -1,17 +1,13 @@ package com.umc.refit.web.filter.authentication; import com.fasterxml.jackson.databind.ObjectMapper; -import com.nimbusds.jose.JOSEException; -import com.nimbusds.jose.jwk.JWK; import com.umc.refit.domain.dto.member.ResLoginDto; import com.umc.refit.domain.entity.Member; import com.umc.refit.exception.member.LoginException; import com.umc.refit.web.service.MemberService; import com.umc.refit.web.service.RefreshTokenService; import com.umc.refit.web.signature.JWTSigner; -import com.umc.refit.web.signature.SecuritySigner; import jakarta.servlet.FilterChain; -import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; @@ -32,9 +28,7 @@ public class JwtAuthenticationFilter extends UsernamePasswordAuthenticationFilter { private final HttpSecurity httpSecurity; -// private final SecuritySigner securitySigner; private final JWTSigner securitySigner; -// private final JWK jwk; private final MemberService memberService; private final RefreshTokenService refreshTokenService; diff --git a/src/main/java/com/umc/refit/web/filter/authentication/JwtKakaoAuthenticationFilter.java b/src/main/java/com/umc/refit/web/filter/authentication/JwtKakaoAuthenticationFilter.java index 80e642c..69d72e9 100644 --- a/src/main/java/com/umc/refit/web/filter/authentication/JwtKakaoAuthenticationFilter.java +++ b/src/main/java/com/umc/refit/web/filter/authentication/JwtKakaoAuthenticationFilter.java @@ -4,13 +4,12 @@ import com.google.gson.JsonElement; import com.google.gson.JsonParser; import com.nimbusds.jose.JOSEException; -import com.nimbusds.jose.jwk.JWK; import com.umc.refit.domain.dto.member.ResLoginDto; import com.umc.refit.domain.entity.Member; import com.umc.refit.exception.member.LoginException; import com.umc.refit.web.service.MemberService; import com.umc.refit.web.service.RefreshTokenService; -import com.umc.refit.web.signature.SecuritySigner; +import com.umc.refit.web.signature.JWTSigner; import jakarta.servlet.FilterChain; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; @@ -38,8 +37,7 @@ public class JwtKakaoAuthenticationFilter extends UsernamePasswordAuthenticationFilter { private final HttpSecurity httpSecurity; - private final SecuritySigner securitySigner; - private final JWK jwk; + private final JWTSigner securitySigner; private final MemberService memberService; private final RefreshTokenService refreshTokenService; @@ -95,27 +93,19 @@ public Authentication attemptAuthentication(HttpServletRequest request, HttpServ @Override protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws ServletException, IOException { User user = (User) authResult.getPrincipal(); - try { - //엑세스 토큰 및 리프레쉬 토큰 발행 - String accessToken = securitySigner.getJwtToken(user, jwk, 216000000); - String refreshToken = securitySigner.getJwtToken(user, jwk, 216000000); - //엑세스 토큰 헤더를 통해 전달 - response.addHeader("Authorization", "Bearer " + accessToken); //발행받은 토큰을 response 헤더에 담아 응답 + String accessToken = securitySigner.getJwtToken(user, 216000000); + String refreshToken = securitySigner.getJwtToken(user, 216000000); - //리프레쉬 토큰 저장 - refreshTokenService.saveRefreshToken(user.getUsername(), refreshToken); + response.addHeader("Authorization", "Bearer " + accessToken); //발행받은 토큰을 response 헤더에 담아 응답 - //리프레쉬 토큰 바디에 담아 전달 - ResLoginDto resEmailDto = new ResLoginDto(refreshToken); - response.setContentType("application/json"); - ObjectMapper objectMapper = new ObjectMapper(); - String jsonString = objectMapper.writeValueAsString(resEmailDto); - response.getWriter().write(jsonString); + refreshTokenService.saveRefreshToken(user.getUsername(), refreshToken); - } catch (JOSEException e) { - e.printStackTrace(); - } + ResLoginDto resEmailDto = new ResLoginDto(refreshToken); + response.setContentType("application/json"); + ObjectMapper objectMapper = new ObjectMapper(); + String jsonString = objectMapper.writeValueAsString(resEmailDto); + response.getWriter().write(jsonString); } /*카카오 인가 서버에 이메일 정보 요청*/ diff --git a/src/main/java/com/umc/refit/web/filter/authorization/JwtAuthorizationRsaFilter.java b/src/main/java/com/umc/refit/web/filter/authorization/JwtAuthorizationRsaFilter.java index 35e3a5e..f6ffa60 100644 --- a/src/main/java/com/umc/refit/web/filter/authorization/JwtAuthorizationRsaFilter.java +++ b/src/main/java/com/umc/refit/web/filter/authorization/JwtAuthorizationRsaFilter.java @@ -1,7 +1,5 @@ package com.umc.refit.web.filter.authorization; -import com.nimbusds.jose.crypto.RSASSAVerifier; -import com.nimbusds.jwt.SignedJWT; import com.umc.refit.exception.ExceptionType; import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; diff --git a/src/main/java/com/umc/refit/web/signature/RSASecuritySigner.java b/src/main/java/com/umc/refit/web/signature/RSASecuritySigner.java deleted file mode 100644 index f0f6262..0000000 --- a/src/main/java/com/umc/refit/web/signature/RSASecuritySigner.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.umc.refit.web.signature; - -import com.nimbusds.jose.JOSEException; -import com.nimbusds.jose.crypto.RSASSASigner; -import com.nimbusds.jose.jwk.JWK; -import com.nimbusds.jose.jwk.RSAKey; -import org.springframework.security.core.userdetails.UserDetails; - -import java.math.BigInteger; - -/*RSA 방식의 토큰을 서명하고 발행하는 클래스*/ -public class RSASecuritySigner extends SecuritySigner { - - //개인키로 서명히고 부모에게 전달 - public String getJwtToken(UserDetails user, JWK jwk, Integer time) throws JOSEException { - - RSASSASigner jwsSigner = new RSASSASigner(((RSAKey)jwk).toRSAPrivateKey()); - - return getJwtTokenInternal(jwsSigner, user, jwk, time); - } -} diff --git a/src/main/java/com/umc/refit/web/signature/SecuritySigner.java b/src/main/java/com/umc/refit/web/signature/SecuritySigner.java deleted file mode 100644 index 0bc3b13..0000000 --- a/src/main/java/com/umc/refit/web/signature/SecuritySigner.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.umc.refit.web.signature; - -import com.nimbusds.jose.JOSEException; -import com.nimbusds.jose.JWSAlgorithm; -import com.nimbusds.jose.JWSHeader; -import com.nimbusds.jose.JWSSigner; -import com.nimbusds.jose.jwk.JWK; -import com.nimbusds.jwt.JWTClaimsSet; -import com.nimbusds.jwt.SignedJWT; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.security.core.userdetails.UserDetails; - -import java.math.BigInteger; -import java.util.Date; -import java.util.List; -import java.util.stream.Collectors; - -public abstract class SecuritySigner { - - @Value("${token.issuer}") - private String issuer; - - /*토큰 발행 메서드*/ - public String getJwtTokenInternal(JWSSigner jwsSigner, UserDetails user, JWK jwk, Integer time) throws JOSEException { - - JWSHeader header= new JWSHeader.Builder((JWSAlgorithm) jwk.getAlgorithm()).keyID(jwk.getKeyID()).build(); - - List authority = user.getAuthorities().stream().map(auth -> auth.getAuthority()).collect(Collectors.toList()); - JWTClaimsSet jwtClaimsSet = new JWTClaimsSet.Builder() - .subject(user.getUsername()) - .issuer(issuer) - .claim("id", user.getUsername()) - .claim("role", authority) - .expirationTime(new Date(new Date().getTime() + time)) - .build(); - - //최종 서명 객체가 SignedJWT 객체 - SignedJWT signedJWT = new SignedJWT(header, jwtClaimsSet); - signedJWT.sign(jwsSigner); - String jwtToken = signedJWT.serialize(); - - //서명에 성공하면 JWT 토큰 발행 - return jwtToken; - } - - //UserDetails가 UserDetailsService 에서 반환된 User 객체 - public abstract String getJwtToken(UserDetails user, JWK jwk, Integer time) throws JOSEException; -} From 99c9793abb0211a44ed5ad2a9f0d07a8874e6abb Mon Sep 17 00:00:00 2001 From: Ji Seungmin Date: Tue, 19 Dec 2023 14:36:18 +0900 Subject: [PATCH 09/13] =?UTF-8?q?refactor:=20=EC=9D=BC=EB=B0=98=20?= =?UTF-8?q?=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=EC=9D=B8=EC=A6=9D=20=ED=95=84?= =?UTF-8?q?=ED=84=B0=20=EA=B5=AC=EC=A1=B0=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../umc/refit/domain/dto/member/LoginDto.java | 11 ++++ .../umc/refit/exception/ExceptionType.java | 2 + .../com/umc/refit/web/config/S3Config.java | 2 - .../umc/refit/web/config/SignatureConfig.java | 4 -- .../web/config/SpringSecurityConfig.java | 1 - .../CustomUserDetailsService.java | 5 +- .../JwtAuthenticationFilter.java | 53 +++++++++++++------ 7 files changed, 52 insertions(+), 26 deletions(-) create mode 100644 src/main/java/com/umc/refit/domain/dto/member/LoginDto.java diff --git a/src/main/java/com/umc/refit/domain/dto/member/LoginDto.java b/src/main/java/com/umc/refit/domain/dto/member/LoginDto.java new file mode 100644 index 0000000..c64236c --- /dev/null +++ b/src/main/java/com/umc/refit/domain/dto/member/LoginDto.java @@ -0,0 +1,11 @@ +package com.umc.refit.domain.dto.member; + +import lombok.Getter; +import lombok.Setter; + +@Getter @Setter +public class LoginDto { + private String loginId; + private String password; + private String fcm; +} \ No newline at end of file diff --git a/src/main/java/com/umc/refit/exception/ExceptionType.java b/src/main/java/com/umc/refit/exception/ExceptionType.java index 1276ae9..83837f5 100644 --- a/src/main/java/com/umc/refit/exception/ExceptionType.java +++ b/src/main/java/com/umc/refit/exception/ExceptionType.java @@ -42,6 +42,8 @@ public enum ExceptionType { LOGIN_FAILED(BAD_REQUEST, 10103, "존재하지 않는 계정입니다."), LOGIN_FAILED_UNKNOWN(BAD_REQUEST, 10104, "알 수 없는 이유로 로그인 할 수 없습니다."), KAKAO_MEMBER_EXIST(BAD_REQUEST, 10105, "카카오 로그인 계정이 존재합니다."), + GOOGLE_MEMBER_EXIST(BAD_REQUEST, 10505, "구글 로그인 계정이 존재합니다."), + NAVER_MEMBER_EXIST(BAD_REQUEST, 10605, "네이버 로그인 계정이 존재합니다."), BASIC_MEMBER_EXIST(BAD_REQUEST, 10106, "일반 로그인 계정이 존재합니다."), diff --git a/src/main/java/com/umc/refit/web/config/S3Config.java b/src/main/java/com/umc/refit/web/config/S3Config.java index 5953bf4..45b64e3 100644 --- a/src/main/java/com/umc/refit/web/config/S3Config.java +++ b/src/main/java/com/umc/refit/web/config/S3Config.java @@ -8,7 +8,6 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.data.jpa.repository.config.EnableJpaAuditing; @Configuration public class S3Config { @@ -31,5 +30,4 @@ public AmazonS3 amazonS3Client() { .withRegion(region) .build(); } - } \ No newline at end of file diff --git a/src/main/java/com/umc/refit/web/config/SignatureConfig.java b/src/main/java/com/umc/refit/web/config/SignatureConfig.java index 6038401..be96a06 100644 --- a/src/main/java/com/umc/refit/web/config/SignatureConfig.java +++ b/src/main/java/com/umc/refit/web/config/SignatureConfig.java @@ -1,9 +1,5 @@ package com.umc.refit.web.config; -import com.nimbusds.jose.JOSEException; -import com.nimbusds.jose.JWSAlgorithm; -import com.nimbusds.jose.jwk.RSAKey; -import com.nimbusds.jose.jwk.gen.RSAKeyGenerator; import io.jsonwebtoken.SignatureAlgorithm; import io.jsonwebtoken.security.Keys; import org.springframework.context.annotation.Bean; diff --git a/src/main/java/com/umc/refit/web/config/SpringSecurityConfig.java b/src/main/java/com/umc/refit/web/config/SpringSecurityConfig.java index 3c1da19..246845e 100644 --- a/src/main/java/com/umc/refit/web/config/SpringSecurityConfig.java +++ b/src/main/java/com/umc/refit/web/config/SpringSecurityConfig.java @@ -1,6 +1,5 @@ package com.umc.refit.web.config; -import com.nimbusds.jose.jwk.RSAKey; import com.umc.refit.web.filter.authentication.CustomUserDetailsService; import com.umc.refit.web.filter.authentication.JwtAuthenticationFilter; import com.umc.refit.web.filter.authentication.JwtKakaoAuthenticationFilter; diff --git a/src/main/java/com/umc/refit/web/filter/authentication/CustomUserDetailsService.java b/src/main/java/com/umc/refit/web/filter/authentication/CustomUserDetailsService.java index bad264b..4372b6b 100644 --- a/src/main/java/com/umc/refit/web/filter/authentication/CustomUserDetailsService.java +++ b/src/main/java/com/umc/refit/web/filter/authentication/CustomUserDetailsService.java @@ -9,6 +9,8 @@ import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Service; +import static com.umc.refit.exception.ExceptionType.MEMBER_IS_NOT_EXIST; + @Service @RequiredArgsConstructor public class CustomUserDetailsService implements UserDetailsService { @@ -20,10 +22,9 @@ public UserDetails loadUserByUsername(String loginId) { return memberRepository.findByLoginId(loginId) .map(this::createUserDetails) .orElseThrow(() -> - new UsernameNotFoundException("사용자를 찾을 수 없습니다")); + new UsernameNotFoundException(MEMBER_IS_NOT_EXIST.getErrorMessage())); } - //Member 데이터가 존재한다면 UserDetails 객체로 만들어서 리턴 private UserDetails createUserDetails(Member member) { return User.builder() .username(member.getLoginId()) diff --git a/src/main/java/com/umc/refit/web/filter/authentication/JwtAuthenticationFilter.java b/src/main/java/com/umc/refit/web/filter/authentication/JwtAuthenticationFilter.java index 4edfc50..750726e 100644 --- a/src/main/java/com/umc/refit/web/filter/authentication/JwtAuthenticationFilter.java +++ b/src/main/java/com/umc/refit/web/filter/authentication/JwtAuthenticationFilter.java @@ -1,6 +1,7 @@ package com.umc.refit.web.filter.authentication; import com.fasterxml.jackson.databind.ObjectMapper; +import com.umc.refit.domain.dto.member.LoginDto; import com.umc.refit.domain.dto.member.ResLoginDto; import com.umc.refit.domain.entity.Member; import com.umc.refit.exception.member.LoginException; @@ -22,7 +23,7 @@ import java.io.IOException; import java.util.Optional; -import static com.umc.refit.exception.ExceptionType.KAKAO_MEMBER_EXIST; +import static com.umc.refit.exception.ExceptionType.*; @RequiredArgsConstructor public class JwtAuthenticationFilter extends UsernamePasswordAuthenticationFilter { @@ -35,28 +36,46 @@ public class JwtAuthenticationFilter extends UsernamePasswordAuthenticationFilte @Override public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { + try { + LoginDto loginDto = new ObjectMapper().readValue(request.getInputStream(), LoginDto.class); - String loginId = request.getParameter("loginId"); - String password = request.getParameter("password"); - String fcm = request.getParameter("fcm"); + String loginId = loginDto.getLoginId(); + String password = loginDto.getPassword(); + String fcm = loginDto.getFcm(); - Optional findMember = memberService.findMemberByLoginId(loginId); + Optional findMember = memberService.findMemberByLoginId(loginId); - if (findMember.isPresent()) { - if (!(findMember.get().getSocialType() == null)) { - throw new LoginException(KAKAO_MEMBER_EXIST, - KAKAO_MEMBER_EXIST.getCode(), KAKAO_MEMBER_EXIST.getErrorMessage()); - } + findMember.ifPresent(member -> { + validateSocialMember(member); + member.setFcm(fcm); + memberService.updateFcm(member); + }); - Member member = findMember.get(); - member.setFcm(fcm); - memberService.updateFcm(member); + AuthenticationManager authenticationManager = httpSecurity.getSharedObject(AuthenticationManager.class); + UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginId, password); + Authentication authentication = authenticationManager.authenticate(authenticationToken); + return authentication; + } catch (IOException e) { + throw new LoginException(LOGIN_FAILED_UNKNOWN, + LOGIN_FAILED_UNKNOWN.getCode(), LOGIN_FAILED_UNKNOWN.getErrorMessage()); + } + } + + private void validateSocialMember(Member member) { + if ("KAKAO".equals(member.getSocialType())) { + throw new LoginException(KAKAO_MEMBER_EXIST, + KAKAO_MEMBER_EXIST.getCode(), KAKAO_MEMBER_EXIST.getErrorMessage()); } - AuthenticationManager authenticationManager = httpSecurity.getSharedObject(AuthenticationManager.class); - UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginId, password); - Authentication authentication = authenticationManager.authenticate(authenticationToken); - return authentication; + if ("GOOGLE".equals(member.getSocialType())) { + throw new LoginException(GOOGLE_MEMBER_EXIST, + GOOGLE_MEMBER_EXIST.getCode(), GOOGLE_MEMBER_EXIST.getErrorMessage()); + } + + if ("NAVER".equals(member.getSocialType())) { + throw new LoginException(NAVER_MEMBER_EXIST, + NAVER_MEMBER_EXIST.getCode(), NAVER_MEMBER_EXIST.getErrorMessage()); + } } @Override From cb20bd04d1d5e34747e057e2e5e0eb8e0f4ea106 Mon Sep 17 00:00:00 2001 From: Ji Seungmin Date: Tue, 19 Dec 2023 14:42:19 +0900 Subject: [PATCH 10/13] =?UTF-8?q?refactor:=20=EC=97=91=EC=84=B8=EC=8A=A4?= =?UTF-8?q?=20=ED=86=A0=ED=81=B0=20=EC=9C=A0=ED=9A=A8=EC=8B=9C=EA=B0=84=20?= =?UTF-8?q?=EC=83=81=EC=88=98=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/umc/refit/Util.java | 7 +++++++ .../authentication/JwtAuthenticationFilter.java | 13 ++++++------- .../JwtKakaoAuthenticationFilter.java | 8 +++++--- 3 files changed, 18 insertions(+), 10 deletions(-) create mode 100644 src/main/java/com/umc/refit/Util.java diff --git a/src/main/java/com/umc/refit/Util.java b/src/main/java/com/umc/refit/Util.java new file mode 100644 index 0000000..0af1aa9 --- /dev/null +++ b/src/main/java/com/umc/refit/Util.java @@ -0,0 +1,7 @@ +package com.umc.refit; + +public class Util { + public static final int ONE_HOUR = 60 * 60 * 1000; + public static final int ONE_DAY = 24 * 60 * 60 * 1000; + public static final int ONE_WEEK = 7 * 24 * 60 * 60 * 1000; +} diff --git a/src/main/java/com/umc/refit/web/filter/authentication/JwtAuthenticationFilter.java b/src/main/java/com/umc/refit/web/filter/authentication/JwtAuthenticationFilter.java index 750726e..b4796b6 100644 --- a/src/main/java/com/umc/refit/web/filter/authentication/JwtAuthenticationFilter.java +++ b/src/main/java/com/umc/refit/web/filter/authentication/JwtAuthenticationFilter.java @@ -23,6 +23,8 @@ import java.io.IOException; import java.util.Optional; +import static com.umc.refit.Util.ONE_HOUR; +import static com.umc.refit.Util.ONE_WEEK; import static com.umc.refit.exception.ExceptionType.*; @RequiredArgsConstructor @@ -82,17 +84,14 @@ private void validateSocialMember(Member member) { protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException { User user = (User) authResult.getPrincipal(); - //엑세스 토큰 및 리프레쉬 토큰 발행 - String accessToken = securitySigner.getJwtToken(user, 216000000); - String refreshToken = securitySigner.getJwtToken(user, 216000000); - //리프레쉬 토큰 저장 + String accessToken = securitySigner.getJwtToken(user, ONE_HOUR); + String refreshToken = securitySigner.getJwtToken(user, ONE_WEEK); + refreshTokenService.saveRefreshToken(user.getUsername(), refreshToken); - //엑세스 토큰 헤더를 통해 전달 - response.addHeader("Authorization", "Bearer " + accessToken); //발행받은 토큰을 response 헤더에 담아 응답 + response.addHeader("Authorization", "Bearer " + accessToken); - //리프레쉬 토큰 바디에 담아 전달 ResLoginDto resEmailDto = new ResLoginDto(refreshToken); response.setContentType("application/json"); ObjectMapper objectMapper = new ObjectMapper(); diff --git a/src/main/java/com/umc/refit/web/filter/authentication/JwtKakaoAuthenticationFilter.java b/src/main/java/com/umc/refit/web/filter/authentication/JwtKakaoAuthenticationFilter.java index 69d72e9..ec0a6c3 100644 --- a/src/main/java/com/umc/refit/web/filter/authentication/JwtKakaoAuthenticationFilter.java +++ b/src/main/java/com/umc/refit/web/filter/authentication/JwtKakaoAuthenticationFilter.java @@ -31,6 +31,8 @@ import java.util.Optional; import java.util.Random; +import static com.umc.refit.Util.ONE_HOUR; +import static com.umc.refit.Util.ONE_WEEK; import static com.umc.refit.exception.ExceptionType.BASIC_MEMBER_EXIST; @RequiredArgsConstructor @@ -94,10 +96,10 @@ public Authentication attemptAuthentication(HttpServletRequest request, HttpServ protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws ServletException, IOException { User user = (User) authResult.getPrincipal(); - String accessToken = securitySigner.getJwtToken(user, 216000000); - String refreshToken = securitySigner.getJwtToken(user, 216000000); + String accessToken = securitySigner.getJwtToken(user, ONE_HOUR); + String refreshToken = securitySigner.getJwtToken(user, ONE_WEEK); - response.addHeader("Authorization", "Bearer " + accessToken); //발행받은 토큰을 response 헤더에 담아 응답 + response.addHeader("Authorization", "Bearer " + accessToken); refreshTokenService.saveRefreshToken(user.getUsername(), refreshToken); From d7e2d3ca3788ef905261e296eeb026f69720f244 Mon Sep 17 00:00:00 2001 From: Ji Seungmin Date: Tue, 19 Dec 2023 15:31:25 +0900 Subject: [PATCH 11/13] =?UTF-8?q?fix:=20=EC=B9=B4=EC=B9=B4=EC=98=A4=20?= =?UTF-8?q?=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=EA=B5=AC=EC=A1=B0=20=EA=B0=9C?= =?UTF-8?q?=EC=84=A0=20=EB=B0=8F=20RestTemplate=EB=A1=9C=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/umc/refit/Util.java | 22 +++ .../com/umc/refit/domain/entity/Member.java | 4 +- .../com/umc/refit/web/config/AppConfig.java | 7 + .../web/config/SpringSecurityConfig.java | 4 +- .../CustomUserDetailsService.java | 6 +- .../JwtAuthenticationFilter.java | 2 +- .../JwtKakaoAuthenticationFilter.java | 143 +++++++----------- 7 files changed, 96 insertions(+), 92 deletions(-) diff --git a/src/main/java/com/umc/refit/Util.java b/src/main/java/com/umc/refit/Util.java index 0af1aa9..cd24064 100644 --- a/src/main/java/com/umc/refit/Util.java +++ b/src/main/java/com/umc/refit/Util.java @@ -1,7 +1,29 @@ package com.umc.refit; +import java.util.Random; + public class Util { + + /**Random 문자열*/ + private static final String CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()"; + + public static String generateRandomString(int length) { + Random random = new Random(); + StringBuilder stringBuilder = new StringBuilder(length); + + for (int i = 0; i < length; i++) { + int randomIndex = random.nextInt(CHARACTERS.length()); + stringBuilder.append(CHARACTERS.charAt(randomIndex)); + } + + return stringBuilder.toString(); + } + + /**시간*/ public static final int ONE_HOUR = 60 * 60 * 1000; public static final int ONE_DAY = 24 * 60 * 60 * 1000; public static final int ONE_WEEK = 7 * 24 * 60 * 60 * 1000; + + /**PATH*/ + public static final String KAKAO_API = "https://kapi.kakao.com/v2/user/me"; } diff --git a/src/main/java/com/umc/refit/domain/entity/Member.java b/src/main/java/com/umc/refit/domain/entity/Member.java index ad314a5..452ace8 100644 --- a/src/main/java/com/umc/refit/domain/entity/Member.java +++ b/src/main/java/com/umc/refit/domain/entity/Member.java @@ -43,10 +43,10 @@ public Member(String name) { this.name = name; } - public Member(String email, String password, String name, String fcm) { + public Member(String email, String name, String fcm) { this.email = email; this.loginId = email; - this.password = password; + this.password = email; this.name = name; this.birth = LocalDate.now().toString().replace('-', '/'); this.gender = 0; diff --git a/src/main/java/com/umc/refit/web/config/AppConfig.java b/src/main/java/com/umc/refit/web/config/AppConfig.java index 34a8d57..a513149 100644 --- a/src/main/java/com/umc/refit/web/config/AppConfig.java +++ b/src/main/java/com/umc/refit/web/config/AppConfig.java @@ -1,9 +1,16 @@ package com.umc.refit.web.config; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.jpa.repository.config.EnableJpaAuditing; +import org.springframework.web.client.RestTemplate; @EnableJpaAuditing @Configuration public class AppConfig { + + @Bean + public RestTemplate restTemplate() { + return new RestTemplate(); + } } diff --git a/src/main/java/com/umc/refit/web/config/SpringSecurityConfig.java b/src/main/java/com/umc/refit/web/config/SpringSecurityConfig.java index 246845e..ff8a35f 100644 --- a/src/main/java/com/umc/refit/web/config/SpringSecurityConfig.java +++ b/src/main/java/com/umc/refit/web/config/SpringSecurityConfig.java @@ -17,6 +17,7 @@ import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; +import org.springframework.web.client.RestTemplate; import java.security.Key; @@ -32,6 +33,7 @@ public class SpringSecurityConfig { private final RefreshTokenService refreshTokenService; private final JWTSigner jwtSigner; private final Key key; + private final RestTemplate restTemplate; private String[] permitAllUrlPatterns() { return new String[] { @@ -62,7 +64,7 @@ SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { jwtAuthenticationFilter.setFilterProcessesUrl("/auth/login"); JwtKakaoAuthenticationFilter jwtKakaoAuthenticationFilter = - new JwtKakaoAuthenticationFilter(http, jwtSigner, memberService, refreshTokenService); + new JwtKakaoAuthenticationFilter(http, jwtSigner, memberService, refreshTokenService, restTemplate); jwtKakaoAuthenticationFilter.setAuthenticationFailureHandler(authFailureHandler); jwtKakaoAuthenticationFilter.setFilterProcessesUrl("/auth/kakao"); diff --git a/src/main/java/com/umc/refit/web/filter/authentication/CustomUserDetailsService.java b/src/main/java/com/umc/refit/web/filter/authentication/CustomUserDetailsService.java index 4372b6b..111e162 100644 --- a/src/main/java/com/umc/refit/web/filter/authentication/CustomUserDetailsService.java +++ b/src/main/java/com/umc/refit/web/filter/authentication/CustomUserDetailsService.java @@ -18,8 +18,8 @@ public class CustomUserDetailsService implements UserDetailsService { private final MemberRepository memberRepository; @Override - public UserDetails loadUserByUsername(String loginId) { - return memberRepository.findByLoginId(loginId) + public UserDetails loadUserByUsername(String email) { + return memberRepository.findByEmail(email) .map(this::createUserDetails) .orElseThrow(() -> new UsernameNotFoundException(MEMBER_IS_NOT_EXIST.getErrorMessage())); @@ -27,7 +27,7 @@ public UserDetails loadUserByUsername(String loginId) { private UserDetails createUserDetails(Member member) { return User.builder() - .username(member.getLoginId()) + .username(member.getEmail()) .password(member.getPassword()) .roles(member.getRoles().toArray(new String[0])) .build(); diff --git a/src/main/java/com/umc/refit/web/filter/authentication/JwtAuthenticationFilter.java b/src/main/java/com/umc/refit/web/filter/authentication/JwtAuthenticationFilter.java index b4796b6..2675361 100644 --- a/src/main/java/com/umc/refit/web/filter/authentication/JwtAuthenticationFilter.java +++ b/src/main/java/com/umc/refit/web/filter/authentication/JwtAuthenticationFilter.java @@ -54,7 +54,7 @@ public Authentication attemptAuthentication(HttpServletRequest request, HttpServ }); AuthenticationManager authenticationManager = httpSecurity.getSharedObject(AuthenticationManager.class); - UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginId, password); + UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(findMember.get().getEmail(), password); Authentication authentication = authenticationManager.authenticate(authenticationToken); return authentication; } catch (IOException e) { diff --git a/src/main/java/com/umc/refit/web/filter/authentication/JwtKakaoAuthenticationFilter.java b/src/main/java/com/umc/refit/web/filter/authentication/JwtKakaoAuthenticationFilter.java index ec0a6c3..112ac62 100644 --- a/src/main/java/com/umc/refit/web/filter/authentication/JwtKakaoAuthenticationFilter.java +++ b/src/main/java/com/umc/refit/web/filter/authentication/JwtKakaoAuthenticationFilter.java @@ -3,7 +3,6 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.google.gson.JsonElement; import com.google.gson.JsonParser; -import com.nimbusds.jose.JOSEException; import com.umc.refit.domain.dto.member.ResLoginDto; import com.umc.refit.domain.entity.Member; import com.umc.refit.exception.member.LoginException; @@ -15,6 +14,10 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.ResponseEntity; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.config.annotation.web.builders.HttpSecurity; @@ -22,18 +25,13 @@ import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.userdetails.User; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; +import org.springframework.web.client.RestClientException; +import org.springframework.web.client.RestTemplate; -import java.io.BufferedReader; import java.io.IOException; -import java.io.InputStreamReader; -import java.net.HttpURLConnection; -import java.net.URL; -import java.util.Optional; -import java.util.Random; - -import static com.umc.refit.Util.ONE_HOUR; -import static com.umc.refit.Util.ONE_WEEK; -import static com.umc.refit.exception.ExceptionType.BASIC_MEMBER_EXIST; +import static com.umc.refit.Util.*; +import static com.umc.refit.Util.KAKAO_API; +import static com.umc.refit.exception.ExceptionType.*; @RequiredArgsConstructor public class JwtKakaoAuthenticationFilter extends UsernamePasswordAuthenticationFilter { @@ -42,54 +40,53 @@ public class JwtKakaoAuthenticationFilter extends UsernamePasswordAuthentication private final JWTSigner securitySigner; private final MemberService memberService; private final RefreshTokenService refreshTokenService; + private final RestTemplate restTemplate; - //랜덤 문자열 - private String CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()"; - - /*카카오 로그인 인증 시작*/ @Override public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { - String KAKAO_API_URL = "https://kapi.kakao.com/v2/user/me"; - String DEFAULT_PASSWORD = "KAKAO_LOGIN"; String accessToken = request.getHeader("Authorization"); String fcm = request.getParameter("fcm"); - String EMAIL = getEmailFromKakao(accessToken, KAKAO_API_URL); - - Optional findMember = memberService.findMemberByEmail(EMAIL); - if (findMember.isPresent()) { //멤버가 존재할 경우 - if (findMember.get().getSocialType() == (null)) { //일반 로그인일 경우 - throw new LoginException(BASIC_MEMBER_EXIST, - BASIC_MEMBER_EXIST.getCode(), BASIC_MEMBER_EXIST.getErrorMessage()); - } - - Member member = findMember.get(); - member.setFcm(fcm); - memberService.updateFcm(member); - } else { - - /*카카오 로그인 시 유일한 멤버 닉네임 생성*/ - String name; - while (true) { - String randomString = generateRandomString(4); - name = "환경지킴이" + randomString; - - Optional member = memberService.findMemberByName(name); - if (member.isEmpty()) { - break; - } - } - - Member member = new Member(EMAIL, DEFAULT_PASSWORD, name, fcm); - memberService.kakaoSave(member); + String userEmail = getEmailFromKakao(accessToken); + findOrCreateMember(userEmail, fcm); + + return authenticateUser(userEmail); + } + + private Member findOrCreateMember(String userEmail, String fcm) { + return memberService.findMemberByEmail(userEmail) + .map(member -> updateMemberFcm(member, fcm)) + .orElseGet(() -> createNewMember(userEmail, fcm)); + } + + private Member updateMemberFcm(Member member, String fcm) { + if (!("KAKAO".equals(member.getSocialType()))) { + throw new LoginException(BASIC_MEMBER_EXIST, + BASIC_MEMBER_EXIST.getCode(), BASIC_MEMBER_EXIST.getErrorMessage()); } + member.setFcm(fcm); + memberService.updateFcm(member); + return member; + } + private Member createNewMember(String userEmail, String fcm) { + String name; + do { + String randomString = generateRandomString(4); + name = "환경지킴이" + randomString; + } while (memberService.findMemberByName(name).isPresent()); + + Member member = new Member(userEmail, name, fcm); + memberService.kakaoSave(member); + return member; + } + + private Authentication authenticateUser(String userEmail) { AuthenticationManager authenticationManager = httpSecurity.getSharedObject(AuthenticationManager.class); - UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(EMAIL, DEFAULT_PASSWORD); - Authentication authentication = authenticationManager.authenticate(authenticationToken); - return authentication; + UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userEmail, userEmail); + return authenticationManager.authenticate(authenticationToken); } @Override @@ -110,44 +107,20 @@ protected void successfulAuthentication(HttpServletRequest request, HttpServletR response.getWriter().write(jsonString); } - /*카카오 인가 서버에 이메일 정보 요청*/ - private String getEmailFromKakao(String accessToken, String KAKAO_API_URL) { - String email = ""; + private String getEmailFromKakao(String accessToken) { try { - URL url = new URL(KAKAO_API_URL); - HttpURLConnection conn = (HttpURLConnection) url.openConnection(); - - conn.setRequestMethod("POST"); - conn.setDoOutput(true); - conn.setRequestProperty("Authorization", "Bearer " + accessToken); - - BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream())); - StringBuilder result = new StringBuilder(); - - String line; - while ((line = br.readLine()) != null) { - result.append(line); - } - - JsonElement element = JsonParser.parseString(result.toString()); - email = element.getAsJsonObject().get("kakao_account").getAsJsonObject().get("email").getAsString(); - br.close(); - } catch (IOException exception) { - exception.printStackTrace(); - } - return email; - } - - /*랜덤 문자열 생성 메서드*/ - public String generateRandomString(int length) { - Random random = new Random(); - StringBuilder stringBuilder = new StringBuilder(length); - - for (int i = 0; i < length; i++) { - int randomIndex = random.nextInt(CHARACTERS.length()); - stringBuilder.append(CHARACTERS.charAt(randomIndex)); + HttpHeaders headers = new HttpHeaders(); + headers.set("Authorization", "Bearer " + accessToken); + HttpEntity entity = new HttpEntity<>(headers); + + ResponseEntity response = restTemplate.exchange( + KAKAO_API, HttpMethod.POST, entity, String.class); + + JsonElement element = JsonParser.parseString(response.getBody()); + return element.getAsJsonObject().get("kakao_account").getAsJsonObject().get("email").getAsString(); + } catch (RestClientException e) { + throw new LoginException(LOGIN_FAILED_UNKNOWN, + LOGIN_FAILED_UNKNOWN.getCode(), LOGIN_FAILED_UNKNOWN.getErrorMessage()); } - - return stringBuilder.toString(); } } From a177ffe329a331032933df293201d3b89110687d Mon Sep 17 00:00:00 2001 From: Ji Seungmin Date: Tue, 19 Dec 2023 16:25:39 +0900 Subject: [PATCH 12/13] =?UTF-8?q?refactor:=20=EC=84=9C=EB=B9=84=EC=8A=A4?= =?UTF-8?q?=20=EB=A1=9C=EC=A7=81=EA=B3=BC=20=EC=BB=A8=ED=8A=B8=EB=A1=A4?= =?UTF-8?q?=EB=9F=AC=20=EB=A1=9C=EC=A7=81=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...{ResLoginDto.java => RefreshTokenDto.java} | 2 +- .../umc/refit/domain/dto/member/TokenDto.java | 13 ++++++++ .../web/controller/MemberController.java | 33 +++++-------------- .../JwtAuthenticationFilter.java | 4 +-- .../JwtKakaoAuthenticationFilter.java | 4 +-- .../umc/refit/web/service/MemberService.java | 23 +++++++++++++ 6 files changed, 49 insertions(+), 30 deletions(-) rename src/main/java/com/umc/refit/domain/dto/member/{ResLoginDto.java => RefreshTokenDto.java} (86%) create mode 100644 src/main/java/com/umc/refit/domain/dto/member/TokenDto.java diff --git a/src/main/java/com/umc/refit/domain/dto/member/ResLoginDto.java b/src/main/java/com/umc/refit/domain/dto/member/RefreshTokenDto.java similarity index 86% rename from src/main/java/com/umc/refit/domain/dto/member/ResLoginDto.java rename to src/main/java/com/umc/refit/domain/dto/member/RefreshTokenDto.java index d424434..fdb2f74 100644 --- a/src/main/java/com/umc/refit/domain/dto/member/ResLoginDto.java +++ b/src/main/java/com/umc/refit/domain/dto/member/RefreshTokenDto.java @@ -6,7 +6,7 @@ @Getter @Setter @AllArgsConstructor -public class ResLoginDto { +public class RefreshTokenDto { private String refreshToken; } diff --git a/src/main/java/com/umc/refit/domain/dto/member/TokenDto.java b/src/main/java/com/umc/refit/domain/dto/member/TokenDto.java new file mode 100644 index 0000000..3ccc83d --- /dev/null +++ b/src/main/java/com/umc/refit/domain/dto/member/TokenDto.java @@ -0,0 +1,13 @@ +package com.umc.refit.domain.dto.member; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Setter; + +@Getter @Setter +@AllArgsConstructor +public class TokenDto { + + private String accessToken; + private String refreshToken; +} diff --git a/src/main/java/com/umc/refit/web/controller/MemberController.java b/src/main/java/com/umc/refit/web/controller/MemberController.java index 8cc9c68..0053e0e 100644 --- a/src/main/java/com/umc/refit/web/controller/MemberController.java +++ b/src/main/java/com/umc/refit/web/controller/MemberController.java @@ -1,8 +1,6 @@ package com.umc.refit.web.controller; import com.fasterxml.jackson.databind.ObjectMapper; -import com.nimbusds.jose.JOSEException; -import com.nimbusds.jose.jwk.JWK; import com.umc.refit.domain.dto.member.*; import com.umc.refit.domain.entity.Member; import com.umc.refit.exception.ExceptionType; @@ -12,15 +10,11 @@ import com.umc.refit.web.service.EmailService; import com.umc.refit.web.service.MemberService; -import com.umc.refit.web.service.RefreshTokenService; - -import com.umc.refit.web.signature.JWTSigner; import jakarta.mail.MessagingException; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.ResponseEntity; import org.springframework.security.core.Authentication; -import org.springframework.security.core.userdetails.User; import org.springframework.web.bind.annotation.*; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; @@ -36,8 +30,6 @@ public class MemberController { private final EmailService emailService; private final MemberService memberService; - private final RefreshTokenService refreshTokenService; - private final JWTSigner securitySigner; @Value("${member.image}") private String imageUrl; @@ -151,8 +143,8 @@ public ResponseEntity logout(Authentication authentication, HttpServletReq throw new TokenException(exception, exception.getCode(), exception.getErrorMessage()); } - String loginId = authentication.getName(); - refreshTokenService.deleteRefreshToken(loginId); + String email = authentication.getName(); + memberService.deleteRefreshToken(email); return ResponseEntity.ok().build(); } @@ -166,30 +158,21 @@ public ResponseEntity token_check() { /*토큰 재발급 API*/ @PostMapping("/token/refresh") public ResponseEntity token_reissue(Authentication authentication, HttpServletRequest request - , HttpServletResponse response) throws JOSEException, IOException { + , HttpServletResponse response) throws IOException { if (authentication == null) { ExceptionType exception = (ExceptionType) request.getAttribute("exception"); throw new TokenException(exception, exception.getCode(), exception.getErrorMessage()); } - //토큰 재발급 코드 - User user = (User) authentication.getPrincipal(); - - String accessToken = securitySigner.getJwtToken(user, 216000000); - String refreshToken = securitySigner.getJwtToken(user, 216000000); - - //리프레쉬 토큰 저장 - refreshTokenService.saveRefreshToken(user.getUsername(), refreshToken); + TokenDto tokenResponse = memberService.refreshAuthenticationToken(authentication); - //엑세스 토큰 헤더를 통해 전달 - response.addHeader("Authorization", "Bearer " + accessToken); //발행받은 토큰을 response 헤더에 담아 응답 - - //리프레쉬 토큰 바디에 담아 전달 - ResLoginDto resEmailDto = new ResLoginDto(refreshToken); + response.addHeader("Authorization", "Bearer " + tokenResponse.getAccessToken()); response.setContentType("application/json"); + + RefreshTokenDto responseDto = new RefreshTokenDto(tokenResponse.getRefreshToken()); ObjectMapper objectMapper = new ObjectMapper(); - String jsonString = objectMapper.writeValueAsString(resEmailDto); + String jsonString = objectMapper.writeValueAsString(responseDto); response.getWriter().write(jsonString); return ResponseEntity.ok().build(); diff --git a/src/main/java/com/umc/refit/web/filter/authentication/JwtAuthenticationFilter.java b/src/main/java/com/umc/refit/web/filter/authentication/JwtAuthenticationFilter.java index 2675361..7ce33bf 100644 --- a/src/main/java/com/umc/refit/web/filter/authentication/JwtAuthenticationFilter.java +++ b/src/main/java/com/umc/refit/web/filter/authentication/JwtAuthenticationFilter.java @@ -2,7 +2,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.umc.refit.domain.dto.member.LoginDto; -import com.umc.refit.domain.dto.member.ResLoginDto; +import com.umc.refit.domain.dto.member.RefreshTokenDto; import com.umc.refit.domain.entity.Member; import com.umc.refit.exception.member.LoginException; import com.umc.refit.web.service.MemberService; @@ -92,7 +92,7 @@ protected void successfulAuthentication(HttpServletRequest request, HttpServletR response.addHeader("Authorization", "Bearer " + accessToken); - ResLoginDto resEmailDto = new ResLoginDto(refreshToken); + RefreshTokenDto resEmailDto = new RefreshTokenDto(refreshToken); response.setContentType("application/json"); ObjectMapper objectMapper = new ObjectMapper(); String jsonString = objectMapper.writeValueAsString(resEmailDto); diff --git a/src/main/java/com/umc/refit/web/filter/authentication/JwtKakaoAuthenticationFilter.java b/src/main/java/com/umc/refit/web/filter/authentication/JwtKakaoAuthenticationFilter.java index 112ac62..0c5539d 100644 --- a/src/main/java/com/umc/refit/web/filter/authentication/JwtKakaoAuthenticationFilter.java +++ b/src/main/java/com/umc/refit/web/filter/authentication/JwtKakaoAuthenticationFilter.java @@ -3,7 +3,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.google.gson.JsonElement; import com.google.gson.JsonParser; -import com.umc.refit.domain.dto.member.ResLoginDto; +import com.umc.refit.domain.dto.member.RefreshTokenDto; import com.umc.refit.domain.entity.Member; import com.umc.refit.exception.member.LoginException; import com.umc.refit.web.service.MemberService; @@ -100,7 +100,7 @@ protected void successfulAuthentication(HttpServletRequest request, HttpServletR refreshTokenService.saveRefreshToken(user.getUsername(), refreshToken); - ResLoginDto resEmailDto = new ResLoginDto(refreshToken); + RefreshTokenDto resEmailDto = new RefreshTokenDto(refreshToken); response.setContentType("application/json"); ObjectMapper objectMapper = new ObjectMapper(); String jsonString = objectMapper.writeValueAsString(resEmailDto); diff --git a/src/main/java/com/umc/refit/web/service/MemberService.java b/src/main/java/com/umc/refit/web/service/MemberService.java index e8982a3..2890a7a 100644 --- a/src/main/java/com/umc/refit/web/service/MemberService.java +++ b/src/main/java/com/umc/refit/web/service/MemberService.java @@ -1,20 +1,28 @@ package com.umc.refit.web.service; +import com.umc.refit.domain.dto.member.TokenDto; import com.umc.refit.domain.entity.Member; import com.umc.refit.web.repository.MemberRepository; +import com.umc.refit.web.signature.JWTSigner; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Value; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.userdetails.User; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import java.util.Optional; +import static com.umc.refit.Util.*; + @Service @RequiredArgsConstructor public class MemberService { private final MemberRepository memberRepository; private final PasswordEncoder passwordEncoder; + private final RefreshTokenService refreshTokenService; + private final JWTSigner securitySigner; @Value("${member.image}") private String imageUrl; @@ -70,4 +78,19 @@ public void updateMemberPassword(Member member, String newPassword) { public boolean isPasswordMatch(String requestCurrentPassword, String encryptPassword) { return passwordEncoder.matches(requestCurrentPassword, encryptPassword); } + + public void deleteRefreshToken(String token) { + refreshTokenService.deleteRefreshToken(token); + return; + } + + public TokenDto refreshAuthenticationToken(Authentication authentication) { + User user = (User) authentication.getPrincipal(); + String accessToken = securitySigner.getJwtToken(user, ONE_HOUR); + String refreshToken = securitySigner.getJwtToken(user, ONE_WEEK); + + refreshTokenService.saveRefreshToken(user.getUsername(), refreshToken); + + return new TokenDto(accessToken, refreshToken); + } } From 8b52b8b3142f734ee527857974a2bbf81202ea17 Mon Sep 17 00:00:00 2001 From: Ji Seungmin Date: Tue, 19 Dec 2023 16:41:32 +0900 Subject: [PATCH 13/13] =?UTF-8?q?refactor:=20=EC=BB=A8=ED=8A=B8=EB=A1=A4?= =?UTF-8?q?=EB=9F=AC=20=EA=B3=84=EC=B8=B5=20=EC=BD=94=EB=93=9C=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../web/controller/MemberController.java | 135 ++---------------- .../refit/web/service/ValidateService.java | 90 ++++++++++++ 2 files changed, 98 insertions(+), 127 deletions(-) create mode 100644 src/main/java/com/umc/refit/web/service/ValidateService.java diff --git a/src/main/java/com/umc/refit/web/controller/MemberController.java b/src/main/java/com/umc/refit/web/controller/MemberController.java index 0053e0e..fba1b8b 100644 --- a/src/main/java/com/umc/refit/web/controller/MemberController.java +++ b/src/main/java/com/umc/refit/web/controller/MemberController.java @@ -10,6 +10,7 @@ import com.umc.refit.web.service.EmailService; import com.umc.refit.web.service.MemberService; +import com.umc.refit.web.service.ValidateService; import jakarta.mail.MessagingException; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Value; @@ -30,60 +31,34 @@ public class MemberController { private final EmailService emailService; private final MemberService memberService; + private final ValidateService validateService; @Value("${member.image}") private String imageUrl; - /*이메일 인증 API*/ @PostMapping("/email") public ResEmailDto email(@RequestBody EmailDto emailDto) throws MessagingException { - String email = emailDto.getEmail(); - emailCheck(email); - + validateService.emailCheck(email); String auth = emailService.sendEmail(emailDto.getEmail()); - return new ResEmailDto(auth); } @PostMapping("/join/name") public void checkName(@RequestBody NameDto nameDto) { String name = nameDto.getName(); - nameCheck(name); + validateService.nameCheck(name); } - /*회원 가입 API*/ @PostMapping("/join") public void join(@RequestBody JoinDto joinDto) { - - String loginId = joinDto.getLoginId(); - String password = joinDto.getPassword(); - String email = joinDto.getEmail(); - String name = joinDto.getName(); - String birth = joinDto.getBirth(); - Integer gender = joinDto.getGender(); - - /*예외 체크*/ - loginIdCheck(loginId); - passwordCheck(password); - emailCheck(email); - nameCheck(name); - birthCheck(birth); - genderCheck(gender); - - /*예외 처리가 끝나면 회원 저장*/ + validateService.validateJoin(joinDto); memberService.save(new Member(joinDto, imageUrl)); } - /*이메일 인증 API*/ @PostMapping("/reset/password") - public void reset(@RequestBody PasswordResetDto passwordResetDto) throws MessagingException { - - String email = passwordResetDto.getEmail(); - String name = passwordResetDto.getName(); - String loginId = passwordResetDto.getLoginId(); - - Optional member = memberService.findMemberForPasswordRest(name, email, loginId); + public void reset(@RequestBody PasswordResetDto dto) throws MessagingException { + Optional member = memberService.findMemberForPasswordRest(dto.getName(), dto.getEmail(), dto.getLoginId()); if (member.isEmpty()) { throw new MemberException(PASSWORD_RESET_FAIL, PASSWORD_RESET_FAIL.getCode(), PASSWORD_RESET_FAIL.getErrorMessage()); @@ -93,48 +68,40 @@ public void reset(@RequestBody PasswordResetDto passwordResetDto) throws Messagi throw new MemberException(PASSWORD_RESET_FAIL, PASSWORD_RESET_FAIL.getCode(), PASSWORD_RESET_FAIL.getErrorMessage()); } - String password = emailService.resetEmail(email, name); + String password = emailService.resetEmail(dto.getEmail(), dto.getName()); Member getMember = member.get(); getMember.setPassword(password); memberService.save(getMember); } - /*아이디 찾기 API*/ @PostMapping("/find/id") public ResIdFindDto findId(@RequestBody IdFindDto idFindDto) { String email = idFindDto.getEmail(); String name = idFindDto.getName(); - /*예외 처리가 끝나면 회원 조회*/ Optional member = memberService.findMemberForFindId(name, email); - /*회원이 조회되지 않으면 예외*/ if (member.isEmpty()) { throw new MemberException(MEMBER_IS_NOT_EXIST, MEMBER_IS_NOT_EXIST.getCode(), MEMBER_IS_NOT_EXIST.getErrorMessage()); } - /*뒤 세글자 ***로 변환*/ String lastThreeReplaced = "***"; String exceptLastThree = member.get().getLoginId().substring(0, member.get().getLoginId().length() - 3); - return new ResIdFindDto(exceptLastThree + lastThreeReplaced); } - /*일반 로그인 API*/ @PostMapping("/login") public ResponseEntity login() { return ResponseEntity.ok().build(); } - /*카카오 로그인 API*/ @PostMapping("/kakao") public ResponseEntity kakao_login() { return ResponseEntity.ok().build(); } - /*로그아웃 API*/ @PostMapping("/logout") public ResponseEntity logout(Authentication authentication, HttpServletRequest request) { @@ -149,13 +116,11 @@ public ResponseEntity logout(Authentication authentication, HttpServletReq return ResponseEntity.ok().build(); } - /*엑세스 토큰 체크 API*/ @GetMapping("/token/check") public ResponseEntity token_check() { return ResponseEntity.ok().build(); } - /*토큰 재발급 API*/ @PostMapping("/token/refresh") public ResponseEntity token_reissue(Authentication authentication, HttpServletRequest request , HttpServletResponse response) throws IOException { @@ -174,90 +139,6 @@ public ResponseEntity token_reissue(Authentication authentication, HttpSer ObjectMapper objectMapper = new ObjectMapper(); String jsonString = objectMapper.writeValueAsString(responseDto); response.getWriter().write(jsonString); - return ResponseEntity.ok().build(); } - - /*로그인 아이디 체크 메서드*/ - private void loginIdCheck(String loginId) { - //예외 코드 10011: 아이디가 비어있을 경우 - if (loginId.strip().equals("")) { - throw new MemberException(ID_EMPTY, ID_EMPTY.getCode(), ID_EMPTY.getErrorMessage()); - } - - //예외 코드 10012: 아이디가 형식에 맞지 않은 경우 - if (!MemberValidator.isLoginValid(loginId)) { - throw new MemberException(ID_INVALID, ID_INVALID.getCode(), ID_INVALID.getErrorMessage()); - } - - //예외 코드 10013: 아이디가 이미 존재하는 경우 - if (memberService.findMemberByLoginId(loginId).isPresent()) { - throw new MemberException(ID_ALREADY_EXIST, ID_ALREADY_EXIST.getCode(), ID_ALREADY_EXIST.getErrorMessage()); - } - } - - /*비밀번호 체크 메서드*/ - private void passwordCheck(String password) { - //예외 코드 10014: 비밀번호는 필수 정보입니다. - if (password.strip().equals("")) { - throw new MemberException(PASSWORD_EMPTY, PASSWORD_EMPTY.getCode(), PASSWORD_EMPTY.getErrorMessage()); - } - - //예외 코드 10015: "8-16자의 영문 대소문자, 숫자, 특수문자 ((!), (_) , (-))를 포합해야합니다. - if (!MemberValidator.isPasswordValid(password)) { - throw new MemberException(PASSWORD_INVALID, PASSWORD_INVALID.getCode(), PASSWORD_INVALID.getErrorMessage()); - } - } - - /*이메일 체크 메서드*/ - private void emailCheck(String email) { - //예외 코드 10016: 이메일이 비어있을 경우 - if (email.strip().equals("")) { - throw new MemberException(EMAIL_EMPTY, EMAIL_EMPTY.getCode(), EMAIL_EMPTY.getErrorMessage()); - } - - //예외 코드 10017: 이미 존재하는 회원일 경우 - if (memberService.findMemberByEmail(email).isPresent()) { - throw new MemberException(EMAIL_ALREADY_EXIST, EMAIL_ALREADY_EXIST.getCode(), EMAIL_ALREADY_EXIST.getErrorMessage()); - } - - //예외 코드 10018: 이메일 형식에 맞지 않을 경우 - if (!MemberValidator.isEmailValid(email)) { - throw new MemberException(EMAIL_INVALID, EMAIL_INVALID.getCode(), EMAIL_INVALID.getErrorMessage()); - } - } - - /*닉네임 체크 메서드*/ - private void nameCheck(String name) { - //예외 코드 10019: 이름이 비어있을 경우 - if (name.strip().equals("")) { - throw new MemberException(NAME_EMPTY, NAME_EMPTY.getCode(), NAME_EMPTY.getErrorMessage()); - } - - //예외 코드 10020: 이미 존재하는 이름일 경우 - if (memberService.findMemberByName(name).isPresent()) { - throw new MemberException(NAME_ALREADY_EXIST, NAME_ALREADY_EXIST.getCode(), NAME_ALREADY_EXIST.getErrorMessage()); - } - } - - /*생일 체크 메서드*/ - private void birthCheck(String birth) { - //예외 코드 10021: 생일이 비어있을 경우 - if (birth.strip().equals("")) { - throw new MemberException(BIRTH_EMPTY, BIRTH_EMPTY.getCode(), BIRTH_EMPTY.getErrorMessage()); - } - - //예외 코드 10022: 생일이 형식에 맞지 않는 경우 - if (!MemberValidator.isBirthValid(birth)) { - throw new MemberException(BIRTH_ALREADY_EXIST, BIRTH_ALREADY_EXIST.getCode(), BIRTH_ALREADY_EXIST.getErrorMessage()); - } - } - - /*성별 체크 메서드*/ - private void genderCheck(Integer gender) { - //예외 코드 10021: 생일이 비어있을 경우 - if (gender == null) { - throw new MemberException(GENDER_EMPTY, GENDER_EMPTY.getCode(), GENDER_EMPTY.getErrorMessage()); - } - } } diff --git a/src/main/java/com/umc/refit/web/service/ValidateService.java b/src/main/java/com/umc/refit/web/service/ValidateService.java new file mode 100644 index 0000000..d85aeea --- /dev/null +++ b/src/main/java/com/umc/refit/web/service/ValidateService.java @@ -0,0 +1,90 @@ +package com.umc.refit.web.service; + +import com.umc.refit.domain.dto.member.JoinDto; +import com.umc.refit.exception.member.MemberException; +import com.umc.refit.exception.validator.MemberValidator; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import static com.umc.refit.exception.ExceptionType.*; +import static com.umc.refit.exception.ExceptionType.GENDER_EMPTY; + +@Service +@RequiredArgsConstructor +public class ValidateService { + + private final MemberService memberService; + + public void validateJoin(JoinDto joinDto) { + loginIdCheck(joinDto.getLoginId()); + passwordCheck(joinDto.getPassword()); + emailCheck(joinDto.getEmail()); + nameCheck(joinDto.getName()); + birthCheck(joinDto.getBirth()); + genderCheck(joinDto.getGender()); + } + + public void loginIdCheck(String loginId) { + if (loginId.strip().equals("")) { + throw new MemberException(ID_EMPTY, ID_EMPTY.getCode(), ID_EMPTY.getErrorMessage()); + } + + if (!MemberValidator.isLoginValid(loginId)) { + throw new MemberException(ID_INVALID, ID_INVALID.getCode(), ID_INVALID.getErrorMessage()); + } + + if (memberService.findMemberByLoginId(loginId).isPresent()) { + throw new MemberException(ID_ALREADY_EXIST, ID_ALREADY_EXIST.getCode(), ID_ALREADY_EXIST.getErrorMessage()); + } + } + + public void passwordCheck(String password) { + if (password.strip().equals("")) { + throw new MemberException(PASSWORD_EMPTY, PASSWORD_EMPTY.getCode(), PASSWORD_EMPTY.getErrorMessage()); + } + + if (!MemberValidator.isPasswordValid(password)) { + throw new MemberException(PASSWORD_INVALID, PASSWORD_INVALID.getCode(), PASSWORD_INVALID.getErrorMessage()); + } + } + + public void emailCheck(String email) { + if (email.strip().equals("")) { + throw new MemberException(EMAIL_EMPTY, EMAIL_EMPTY.getCode(), EMAIL_EMPTY.getErrorMessage()); + } + + if (memberService.findMemberByEmail(email).isPresent()) { + throw new MemberException(EMAIL_ALREADY_EXIST, EMAIL_ALREADY_EXIST.getCode(), EMAIL_ALREADY_EXIST.getErrorMessage()); + } + + if (!MemberValidator.isEmailValid(email)) { + throw new MemberException(EMAIL_INVALID, EMAIL_INVALID.getCode(), EMAIL_INVALID.getErrorMessage()); + } + } + + public void nameCheck(String name) { + if (name.strip().equals("")) { + throw new MemberException(NAME_EMPTY, NAME_EMPTY.getCode(), NAME_EMPTY.getErrorMessage()); + } + + if (memberService.findMemberByName(name).isPresent()) { + throw new MemberException(NAME_ALREADY_EXIST, NAME_ALREADY_EXIST.getCode(), NAME_ALREADY_EXIST.getErrorMessage()); + } + } + + public void birthCheck(String birth) { + if (birth.strip().equals("")) { + throw new MemberException(BIRTH_EMPTY, BIRTH_EMPTY.getCode(), BIRTH_EMPTY.getErrorMessage()); + } + + if (!MemberValidator.isBirthValid(birth)) { + throw new MemberException(BIRTH_ALREADY_EXIST, BIRTH_ALREADY_EXIST.getCode(), BIRTH_ALREADY_EXIST.getErrorMessage()); + } + } + + public void genderCheck(Integer gender) { + if (gender == null) { + throw new MemberException(GENDER_EMPTY, GENDER_EMPTY.getCode(), GENDER_EMPTY.getErrorMessage()); + } + } +}