From 25e4eeee7d7b19e8a23c80e5a1f078f816d61d14 Mon Sep 17 00:00:00 2001 From: kkangh00n Date: Tue, 26 Dec 2023 11:23:59 +0900 Subject: [PATCH 01/23] =?UTF-8?q?chore:=20OAuth2.0=20=EC=9D=98=EC=A1=B4?= =?UTF-8?q?=EC=84=B1=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 3 +++ 1 file changed, 3 insertions(+) diff --git a/build.gradle b/build.gradle index 57f64ad1..92614a8e 100644 --- a/build.gradle +++ b/build.gradle @@ -49,6 +49,9 @@ dependencies { asciidoctorExt 'org.springframework.restdocs:spring-restdocs-asciidoctor' testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc' + //OAuth2.0 Client + implementation 'org.springframework.boot:spring-boot-starter-oauth2-client' + } tasks.named('test') { From 8281ed2c6cca092bac3a4f3182bb0c67084ecc8e Mon Sep 17 00:00:00 2001 From: kkangh00n Date: Tue, 26 Dec 2023 20:30:48 +0900 Subject: [PATCH 02/23] =?UTF-8?q?feat=20:=20Member=20=EB=8F=84=EB=A9=94?= =?UTF-8?q?=EC=9D=B8=20email=20=ED=95=84=EB=93=9C=20=EC=B6=94=EA=B0=80=20&?= =?UTF-8?q?=20=EC=95=8C=EB=A6=BC=20=EC=97=AC=EB=B6=80=20=EA=B8=B0=EB=B3=B8?= =?UTF-8?q?=EA=B0=92=20true=EB=A1=9C=20=EC=B4=88=EA=B8=B0=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/prgrms/catchtable/member/domain/Member.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/prgrms/catchtable/member/domain/Member.java b/src/main/java/com/prgrms/catchtable/member/domain/Member.java index 54043c59..5d076350 100644 --- a/src/main/java/com/prgrms/catchtable/member/domain/Member.java +++ b/src/main/java/com/prgrms/catchtable/member/domain/Member.java @@ -28,6 +28,9 @@ public class Member extends BaseEntity { @Column(name = "member_name") private String name; + @Column(name = "email") + private String email; + @Column(name = "phone_number") private String phoneNumber; @@ -42,12 +45,12 @@ public class Member extends BaseEntity { private boolean notification_activated; @Builder - public Member(String name, String phoneNumber, Gender gender, LocalDate dateBirth, - boolean notification_activated) { + public Member(String name, String email, String phoneNumber, Gender gender, LocalDate dateBirth) { this.name = name; + this.email = email; this.phoneNumber = phoneNumber; this.gender = gender; this.dateBirth = dateBirth; - this.notification_activated = notification_activated; + this.notification_activated = true; } } From 81722d6a09bdb7591d38baa02e986b34027e4ed5 Mon Sep 17 00:00:00 2001 From: kkangh00n Date: Tue, 26 Dec 2023 20:33:42 +0900 Subject: [PATCH 03/23] =?UTF-8?q?feat=20:=20=EC=86=8C=EC=85=9C=20=EB=A1=9C?= =?UTF-8?q?=EA=B7=B8=EC=9D=B8=20=EC=82=AC=EC=9A=A9=EC=9E=90=20=EC=A0=95?= =?UTF-8?q?=EB=B3=B4=20=EC=A1=B0=ED=9A=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../security/dto/OAuthAttribute.java | 65 +++++++++++++++++++ .../service/CustomOAuth2SuccessHandler.java | 38 +++++++++++ 2 files changed, 103 insertions(+) create mode 100644 src/main/java/com/prgrms/catchtable/security/dto/OAuthAttribute.java create mode 100644 src/main/java/com/prgrms/catchtable/security/service/CustomOAuth2SuccessHandler.java diff --git a/src/main/java/com/prgrms/catchtable/security/dto/OAuthAttribute.java b/src/main/java/com/prgrms/catchtable/security/dto/OAuthAttribute.java new file mode 100644 index 00000000..8c0d689c --- /dev/null +++ b/src/main/java/com/prgrms/catchtable/security/dto/OAuthAttribute.java @@ -0,0 +1,65 @@ +package com.prgrms.catchtable.security.dto; + +import java.util.Map; +import lombok.Builder; +import lombok.Getter; +import org.springframework.security.oauth2.core.user.OAuth2User; + +@Getter +public class OAuthAttribute { + + String name; + + String email; + + String phoneNumber; + + String birthYear; + + String birthDay; + + String gender; + + @Builder + public OAuthAttribute(String name, String email, String phoneNumber, String birthYear, + String birthDay, String gender) { + this.name = name; + this.email = email; + this.phoneNumber = phoneNumber; + this.birthYear = birthYear; + this.birthDay = birthDay; + this.gender = gender; + } + + public static OAuthAttribute of(OAuth2User oAuth2User, String provider) { + + OAuthAttribute oAuthAttribute; + + if (provider.equals("kakao")) { + Map userAttributes = oAuth2User.getAttributes(); + Map kakaoAccount = (Map) userAttributes.get( + "kakao_account"); + Map profile = (Map) kakaoAccount.get("profile"); + + String nickName = (String) profile.get("nickname"); + String email = (String) kakaoAccount.get("email"); + String phoneNumber = (String) kakaoAccount.get("phone_number"); + String birthYear = (String) kakaoAccount.get("birthyear"); + String birthDay = (String) kakaoAccount.get("birthday"); + String gender = (String) kakaoAccount.get("gender"); + + oAuthAttribute = OAuthAttribute.builder() + .name(nickName) + .email(email) + .phoneNumber(phoneNumber) + .birthYear(birthYear) + .birthDay(birthDay) + .gender(gender) + .build(); + } else { + oAuthAttribute = null; + } + + return oAuthAttribute; + } +} diff --git a/src/main/java/com/prgrms/catchtable/security/service/CustomOAuth2SuccessHandler.java b/src/main/java/com/prgrms/catchtable/security/service/CustomOAuth2SuccessHandler.java new file mode 100644 index 00000000..7ea9b399 --- /dev/null +++ b/src/main/java/com/prgrms/catchtable/security/service/CustomOAuth2SuccessHandler.java @@ -0,0 +1,38 @@ +package com.prgrms.catchtable.security.service; + +import com.prgrms.catchtable.member.service.MemberService; +import com.prgrms.catchtable.security.dto.OAuthAttribute; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import java.io.IOException; +import lombok.RequiredArgsConstructor; +import org.springframework.security.core.Authentication; +import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken; +import org.springframework.security.oauth2.core.user.OAuth2User; +import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor +public class CustomOAuth2SuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler { + + private final MemberService memberService; + + @Override + public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, + Authentication authentication) throws IOException { + + if (authentication instanceof OAuth2AuthenticationToken) { + OAuth2User oauth2User = ((OAuth2AuthenticationToken) authentication).getPrincipal(); + String provider = ((OAuth2AuthenticationToken) authentication).getAuthorizedClientRegistrationId(); + + OAuthAttribute oAuthAttribute = OAuthAttribute.of(oauth2User, provider); + + //JWT 토큰 함께 발급 + memberService.oauthLogin(oAuthAttribute); + + //JWT 토큰을 Json으로 전달 + + } + } +} From ab72dac365b29c2829764aa47f61c1dee61417a4 Mon Sep 17 00:00:00 2001 From: kkangh00n Date: Tue, 26 Dec 2023 20:36:49 +0900 Subject: [PATCH 04/23] =?UTF-8?q?feat=20:=20=EC=86=8C=EC=85=9C=20=EB=A1=9C?= =?UTF-8?q?=EA=B7=B8=EC=9D=B8=20=EC=82=AC=EC=9A=A9=EC=9E=90=20=EA=B0=80?= =?UTF-8?q?=EC=9E=85=20=EC=97=AC=EB=B6=80=20=ED=99=95=EC=9D=B8=20=ED=9B=84?= =?UTF-8?q?=20=EC=A0=80=EC=9E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../catchtable/member/dto/MemberMapper.java | 27 ++++++++++++++++ .../member/repository/MemberRepository.java | 3 ++ .../member/service/MemberService.java | 31 +++++++++++++++++++ 3 files changed, 61 insertions(+) create mode 100644 src/main/java/com/prgrms/catchtable/member/dto/MemberMapper.java create mode 100644 src/main/java/com/prgrms/catchtable/member/service/MemberService.java diff --git a/src/main/java/com/prgrms/catchtable/member/dto/MemberMapper.java b/src/main/java/com/prgrms/catchtable/member/dto/MemberMapper.java new file mode 100644 index 00000000..9ac1f9c0 --- /dev/null +++ b/src/main/java/com/prgrms/catchtable/member/dto/MemberMapper.java @@ -0,0 +1,27 @@ +package com.prgrms.catchtable.member.dto; + +import com.prgrms.catchtable.member.domain.Gender; +import com.prgrms.catchtable.member.domain.Member; +import com.prgrms.catchtable.security.dto.OAuthAttribute; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; + +public class MemberMapper { + + public static Member changeOAuth(OAuthAttribute attributes) { + + String birthString = attributes.getBirthYear() + attributes.getBirthDay(); + DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMdd"); + LocalDate birthDay = LocalDate.parse(birthString, dateTimeFormatter); + System.out.println(birthDay); + + return Member.builder() + .name(attributes.getName()) + .email(attributes.getEmail()) + .phoneNumber(attributes.getPhoneNumber()) + .gender(attributes.getGender().equals("male") ? Gender.MALE : Gender.FEMALE) + .dateBirth(birthDay) + .build(); + } + +} diff --git a/src/main/java/com/prgrms/catchtable/member/repository/MemberRepository.java b/src/main/java/com/prgrms/catchtable/member/repository/MemberRepository.java index 2d55246a..ba205c5b 100644 --- a/src/main/java/com/prgrms/catchtable/member/repository/MemberRepository.java +++ b/src/main/java/com/prgrms/catchtable/member/repository/MemberRepository.java @@ -1,8 +1,11 @@ package com.prgrms.catchtable.member.repository; import com.prgrms.catchtable.member.domain.Member; +import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; public interface MemberRepository extends JpaRepository { + Optional findMemberByEmail(String email); + } diff --git a/src/main/java/com/prgrms/catchtable/member/service/MemberService.java b/src/main/java/com/prgrms/catchtable/member/service/MemberService.java new file mode 100644 index 00000000..2803023c --- /dev/null +++ b/src/main/java/com/prgrms/catchtable/member/service/MemberService.java @@ -0,0 +1,31 @@ +package com.prgrms.catchtable.member.service; + +import com.prgrms.catchtable.member.domain.Member; +import com.prgrms.catchtable.member.dto.MemberMapper; +import com.prgrms.catchtable.member.repository.MemberRepository; +import com.prgrms.catchtable.security.dto.OAuthAttribute; +import java.util.Optional; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class MemberService { + + private final MemberRepository memberRepository; + + @Transactional + public void oauthLogin(OAuthAttribute attributes) { + String email = attributes.getEmail(); + Optional optionalMember = memberRepository.findMemberByEmail(email); + + if (optionalMember.isEmpty()) { + Member entity = MemberMapper.changeOAuth(attributes); + memberRepository.save(entity); + } + + //JWT 토큰 생성 & 반환 + } + +} From 55a743ceb12917582d3a3a6293637840093da5d1 Mon Sep 17 00:00:00 2001 From: kkangh00n Date: Tue, 26 Dec 2023 20:37:29 +0900 Subject: [PATCH 05/23] =?UTF-8?q?feat=20:=20OAuth2.0=20=EC=BB=A4=EC=8A=A4?= =?UTF-8?q?=ED=85=80=20=EB=A1=9C=EC=A7=81=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../security/config/SecurityConfig.java | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 src/main/java/com/prgrms/catchtable/security/config/SecurityConfig.java diff --git a/src/main/java/com/prgrms/catchtable/security/config/SecurityConfig.java b/src/main/java/com/prgrms/catchtable/security/config/SecurityConfig.java new file mode 100644 index 00000000..6de948cf --- /dev/null +++ b/src/main/java/com/prgrms/catchtable/security/config/SecurityConfig.java @@ -0,0 +1,37 @@ +package com.prgrms.catchtable.security.config; + +import com.prgrms.catchtable.security.service.CustomOAuth2SuccessHandler; +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Bean; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; +import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.util.matcher.AntPathRequestMatcher; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor +@EnableWebSecurity +public class SecurityConfig { + + private final CustomOAuth2SuccessHandler successHandler; + + @Bean + public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { + + http + .csrf(AbstractHttpConfigurer::disable) + .sessionManagement(sessionManagement -> sessionManagement.sessionCreationPolicy( + SessionCreationPolicy.STATELESS)) + .formLogin(AbstractHttpConfigurer::disable) + .authorizeHttpRequests(authorization -> authorization + .requestMatchers(new AntPathRequestMatcher("/**")).permitAll() + ) + .oauth2Login(oauth2Login -> oauth2Login.successHandler(successHandler)); + + return http.build(); + } + +} From 099c46066db770ad5cd3ed9648c2ca2672371ca0 Mon Sep 17 00:00:00 2001 From: kkangh00n Date: Tue, 26 Dec 2023 20:52:37 +0900 Subject: [PATCH 06/23] =?UTF-8?q?chore=20:=20JWT=20=EC=9D=98=EC=A1=B4?= =?UTF-8?q?=EC=84=B1=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/build.gradle b/build.gradle index 92614a8e..86b3657b 100644 --- a/build.gradle +++ b/build.gradle @@ -52,6 +52,11 @@ dependencies { //OAuth2.0 Client implementation 'org.springframework.boot:spring-boot-starter-oauth2-client' + //JWT + implementation 'io.jsonwebtoken:jjwt-api:0.11.5' + runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5' + runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.5' + } tasks.named('test') { From ca90a5f520f04ceb2625f2bfd4cfffad981f7bd1 Mon Sep 17 00:00:00 2001 From: kkangh00n Date: Tue, 26 Dec 2023 22:56:02 +0900 Subject: [PATCH 07/23] =?UTF-8?q?feat=20:=20JWT=20properties=20=EA=B0=9D?= =?UTF-8?q?=EC=B2=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../prgrms/catchtable/jwt/config/JwtConfig.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 src/main/java/com/prgrms/catchtable/jwt/config/JwtConfig.java diff --git a/src/main/java/com/prgrms/catchtable/jwt/config/JwtConfig.java b/src/main/java/com/prgrms/catchtable/jwt/config/JwtConfig.java new file mode 100644 index 00000000..1f51fefc --- /dev/null +++ b/src/main/java/com/prgrms/catchtable/jwt/config/JwtConfig.java @@ -0,0 +1,16 @@ +package com.prgrms.catchtable.jwt.config; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +@Component +@Data +@ConfigurationProperties(prefix = "jwt") +public class JwtConfig { + + private String clientSecret; + private int expiryMinute; + private int expiryMinuteRefresh; + +} From 708f60230988f1ddeb301f08a7eedf1b719654d2 Mon Sep 17 00:00:00 2001 From: kkangh00n Date: Tue, 26 Dec 2023 22:56:49 +0900 Subject: [PATCH 08/23] =?UTF-8?q?feat=20:=20=ED=9A=8C=EC=9B=90=20=EB=A1=9C?= =?UTF-8?q?=EA=B7=B8=EC=9D=B8=20=EC=8B=9C=20JWT=20=ED=86=A0=ED=81=B0=20?= =?UTF-8?q?=EB=B0=9C=EA=B8=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jwt/provider/JwtTokenProvider.java | 54 +++++++++++++++++++ .../prgrms/catchtable/jwt/token/Token.java | 15 ++++++ .../member/service/MemberService.java | 9 ++-- 3 files changed, 75 insertions(+), 3 deletions(-) create mode 100644 src/main/java/com/prgrms/catchtable/jwt/provider/JwtTokenProvider.java create mode 100644 src/main/java/com/prgrms/catchtable/jwt/token/Token.java diff --git a/src/main/java/com/prgrms/catchtable/jwt/provider/JwtTokenProvider.java b/src/main/java/com/prgrms/catchtable/jwt/provider/JwtTokenProvider.java new file mode 100644 index 00000000..3bfb4819 --- /dev/null +++ b/src/main/java/com/prgrms/catchtable/jwt/provider/JwtTokenProvider.java @@ -0,0 +1,54 @@ +package com.prgrms.catchtable.jwt.provider; + + +import com.prgrms.catchtable.jwt.config.JwtConfig; +import com.prgrms.catchtable.jwt.token.Token; +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.SignatureAlgorithm; +import java.util.Date; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor +public class JwtTokenProvider { + + private final JwtConfig jwtConfig; + + public Token createToken(String email) { + + Claims claims = Jwts.claims().setSubject(email); + Date now = new Date(); + + String accessToken = createAccessToken(claims, now); + String refreshToken = createRefreshToken(claims, now); + + return new Token(accessToken, refreshToken, email); + + } + + private String createAccessToken(Claims claims, Date now) { + long expiryMinute = jwtConfig.getExpiryMinute() * 1000L * 60; + + return Jwts.builder() + .setClaims(claims) + .setIssuedAt(now) + .setExpiration(new Date(now.getTime() + expiryMinute)) + .signWith(SignatureAlgorithm.HS256, jwtConfig.getClientSecret()) + .compact(); + } + + private String createRefreshToken(Claims claims, Date now) { + + long expiryMinuteRefresh = jwtConfig.getExpiryMinuteRefresh() * 1000L * 60; + + return Jwts.builder() + .setClaims(claims) + .setIssuedAt(now) + .setExpiration(new Date(now.getTime() + expiryMinuteRefresh)) + .signWith(SignatureAlgorithm.HS256, jwtConfig.getClientSecret()) + .compact(); + } + +} diff --git a/src/main/java/com/prgrms/catchtable/jwt/token/Token.java b/src/main/java/com/prgrms/catchtable/jwt/token/Token.java new file mode 100644 index 00000000..f2fe8093 --- /dev/null +++ b/src/main/java/com/prgrms/catchtable/jwt/token/Token.java @@ -0,0 +1,15 @@ +package com.prgrms.catchtable.jwt.token; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class Token { + + private String accessToken; + + private String refreshToken; + + private String email; +} diff --git a/src/main/java/com/prgrms/catchtable/member/service/MemberService.java b/src/main/java/com/prgrms/catchtable/member/service/MemberService.java index 2803023c..c123c4ad 100644 --- a/src/main/java/com/prgrms/catchtable/member/service/MemberService.java +++ b/src/main/java/com/prgrms/catchtable/member/service/MemberService.java @@ -1,5 +1,7 @@ package com.prgrms.catchtable.member.service; +import com.prgrms.catchtable.jwt.provider.JwtTokenProvider; +import com.prgrms.catchtable.jwt.token.Token; import com.prgrms.catchtable.member.domain.Member; import com.prgrms.catchtable.member.dto.MemberMapper; import com.prgrms.catchtable.member.repository.MemberRepository; @@ -15,8 +17,10 @@ public class MemberService { private final MemberRepository memberRepository; + private final JwtTokenProvider jwtTokenProvider; + @Transactional - public void oauthLogin(OAuthAttribute attributes) { + public Token oauthLogin(OAuthAttribute attributes) { String email = attributes.getEmail(); Optional optionalMember = memberRepository.findMemberByEmail(email); @@ -25,7 +29,6 @@ public void oauthLogin(OAuthAttribute attributes) { memberRepository.save(entity); } - //JWT 토큰 생성 & 반환 + return jwtTokenProvider.createToken(email); } - } From c72c0810dbb11ed98cab995fb852e4d70ff2c424 Mon Sep 17 00:00:00 2001 From: kkangh00n Date: Tue, 26 Dec 2023 23:03:30 +0900 Subject: [PATCH 09/23] =?UTF-8?q?feat=20:=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20?= =?UTF-8?q?=EC=99=84=EB=A3=8C=20=ED=9B=84=20=EB=B0=9C=EA=B8=89=EB=90=9C=20?= =?UTF-8?q?JWT=20=ED=86=A0=ED=81=B0=EC=9D=84=20JSON=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EC=A0=84=EB=8B=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/CustomOAuth2SuccessHandler.java | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/prgrms/catchtable/security/service/CustomOAuth2SuccessHandler.java b/src/main/java/com/prgrms/catchtable/security/service/CustomOAuth2SuccessHandler.java index 7ea9b399..94830052 100644 --- a/src/main/java/com/prgrms/catchtable/security/service/CustomOAuth2SuccessHandler.java +++ b/src/main/java/com/prgrms/catchtable/security/service/CustomOAuth2SuccessHandler.java @@ -1,5 +1,8 @@ package com.prgrms.catchtable.security.service; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.prgrms.catchtable.jwt.token.Token; import com.prgrms.catchtable.member.service.MemberService; import com.prgrms.catchtable.security.dto.OAuthAttribute; import jakarta.servlet.http.HttpServletRequest; @@ -28,11 +31,22 @@ public void onAuthenticationSuccess(HttpServletRequest request, HttpServletRespo OAuthAttribute oAuthAttribute = OAuthAttribute.of(oauth2User, provider); - //JWT 토큰 함께 발급 - memberService.oauthLogin(oAuthAttribute); - - //JWT 토큰을 Json으로 전달 + Token token = memberService.oauthLogin(oAuthAttribute); + sendTokenJson(response, tokenToJson(token)); } } + + public String tokenToJson(Token token) throws JsonProcessingException { + ObjectMapper objectMapper = new ObjectMapper(); + return objectMapper.writeValueAsString(token); + } + + private void sendTokenJson(HttpServletResponse response, String tokenJson) throws IOException { + response.setContentType("application/json;charset=UTF-8"); + response.setContentLength(tokenJson.getBytes().length); + response.getWriter().write(tokenJson); + } + + } From 6843ab09a6c5bb1c418b2e064896d10add114343 Mon Sep 17 00:00:00 2001 From: kkangh00n Date: Tue, 26 Dec 2023 23:47:02 +0900 Subject: [PATCH 10/23] =?UTF-8?q?feat=20:=20RefreshToken=20=EC=A0=80?= =?UTF-8?q?=EC=9E=A5=EC=9D=84=20=EC=9C=84=ED=95=9C=20=ED=85=8C=EC=9D=B4?= =?UTF-8?q?=EB=B8=94=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../catchtable/jwt/domain/RefreshToken.java | 35 +++++++++++++++++++ .../repository/RefreshTokenRepository.java | 7 ++++ 2 files changed, 42 insertions(+) create mode 100644 src/main/java/com/prgrms/catchtable/jwt/domain/RefreshToken.java create mode 100644 src/main/java/com/prgrms/catchtable/jwt/repository/RefreshTokenRepository.java diff --git a/src/main/java/com/prgrms/catchtable/jwt/domain/RefreshToken.java b/src/main/java/com/prgrms/catchtable/jwt/domain/RefreshToken.java new file mode 100644 index 00000000..b6ef9087 --- /dev/null +++ b/src/main/java/com/prgrms/catchtable/jwt/domain/RefreshToken.java @@ -0,0 +1,35 @@ +package com.prgrms.catchtable.jwt.domain; + +import static lombok.AccessLevel.PROTECTED; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor(access = PROTECTED) +@Entity +public class RefreshToken { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(name = "token") + private String token; + + @Column(name = "email") + private String email; + + @Builder + public RefreshToken(String token, String email) { + this.token = token; + this.email = email; + } + +} diff --git a/src/main/java/com/prgrms/catchtable/jwt/repository/RefreshTokenRepository.java b/src/main/java/com/prgrms/catchtable/jwt/repository/RefreshTokenRepository.java new file mode 100644 index 00000000..1c7c1e6d --- /dev/null +++ b/src/main/java/com/prgrms/catchtable/jwt/repository/RefreshTokenRepository.java @@ -0,0 +1,7 @@ +package com.prgrms.catchtable.jwt.repository; + +import com.prgrms.catchtable.jwt.domain.RefreshToken; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface RefreshTokenRepository extends JpaRepository { +} From c7d91a4a12403cd5fb3dca990750d51a52d1a1ba Mon Sep 17 00:00:00 2001 From: kkangh00n Date: Tue, 26 Dec 2023 23:48:05 +0900 Subject: [PATCH 11/23] =?UTF-8?q?feat=20:=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20?= =?UTF-8?q?=EC=8B=9C,=20RefreshToken=20=ED=85=8C=EC=9D=B4=EB=B8=94?= =?UTF-8?q?=EC=97=90=20=EC=A0=80=EC=9E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/RefreshTokenRepository.java | 4 +++ .../jwt/service/RefreshTokenService.java | 32 +++++++++++++++++++ .../member/service/MemberService.java | 11 ++++++- 3 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/prgrms/catchtable/jwt/service/RefreshTokenService.java diff --git a/src/main/java/com/prgrms/catchtable/jwt/repository/RefreshTokenRepository.java b/src/main/java/com/prgrms/catchtable/jwt/repository/RefreshTokenRepository.java index 1c7c1e6d..5caaed13 100644 --- a/src/main/java/com/prgrms/catchtable/jwt/repository/RefreshTokenRepository.java +++ b/src/main/java/com/prgrms/catchtable/jwt/repository/RefreshTokenRepository.java @@ -4,4 +4,8 @@ import org.springframework.data.jpa.repository.JpaRepository; public interface RefreshTokenRepository extends JpaRepository { + + boolean existsRefreshTokenByEmail(String email); + + void deleteRefreshTokenByEmail(String email); } diff --git a/src/main/java/com/prgrms/catchtable/jwt/service/RefreshTokenService.java b/src/main/java/com/prgrms/catchtable/jwt/service/RefreshTokenService.java new file mode 100644 index 00000000..7683ba73 --- /dev/null +++ b/src/main/java/com/prgrms/catchtable/jwt/service/RefreshTokenService.java @@ -0,0 +1,32 @@ +package com.prgrms.catchtable.jwt.service; + +import com.prgrms.catchtable.jwt.domain.RefreshToken; +import com.prgrms.catchtable.jwt.repository.RefreshTokenRepository; +import com.prgrms.catchtable.jwt.token.Token; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class RefreshTokenService { + + private final RefreshTokenRepository refreshTokenRepository; + + @Transactional + public void saveRefreshToken(Token totalToken){ + String email = totalToken.getEmail(); + + if(refreshTokenRepository.existsRefreshTokenByEmail(email)){ + refreshTokenRepository.deleteRefreshTokenByEmail(email); + } + + RefreshToken newRefreshToken = RefreshToken.builder() + .token(totalToken.getRefreshToken()) + .email(email) + .build(); + + refreshTokenRepository.save(newRefreshToken); + } + +} diff --git a/src/main/java/com/prgrms/catchtable/member/service/MemberService.java b/src/main/java/com/prgrms/catchtable/member/service/MemberService.java index c123c4ad..7ce7aed7 100644 --- a/src/main/java/com/prgrms/catchtable/member/service/MemberService.java +++ b/src/main/java/com/prgrms/catchtable/member/service/MemberService.java @@ -1,6 +1,7 @@ package com.prgrms.catchtable.member.service; import com.prgrms.catchtable.jwt.provider.JwtTokenProvider; +import com.prgrms.catchtable.jwt.service.RefreshTokenService; import com.prgrms.catchtable.jwt.token.Token; import com.prgrms.catchtable.member.domain.Member; import com.prgrms.catchtable.member.dto.MemberMapper; @@ -19,6 +20,8 @@ public class MemberService { private final JwtTokenProvider jwtTokenProvider; + private final RefreshTokenService refreshTokenService; + @Transactional public Token oauthLogin(OAuthAttribute attributes) { String email = attributes.getEmail(); @@ -29,6 +32,12 @@ public Token oauthLogin(OAuthAttribute attributes) { memberRepository.save(entity); } - return jwtTokenProvider.createToken(email); + return createTotalToken(email); + } + + private Token createTotalToken(String email){ + Token totalToken = jwtTokenProvider.createToken(email); + refreshTokenService.saveRefreshToken(totalToken); + return totalToken; } } From 459dac8c12bc8b890a32b8faae1764084a8ceb9b Mon Sep 17 00:00:00 2001 From: kkangh00n Date: Wed, 27 Dec 2023 00:31:59 +0900 Subject: [PATCH 12/23] =?UTF-8?q?feat=20:=20=EC=9D=B8=EA=B0=80=EB=A5=BC=20?= =?UTF-8?q?=EC=9C=84=ED=95=B4=20Member=20Role=20=ED=95=84=EB=93=9C=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/prgrms/catchtable/common/Role.java | 14 ++++++ .../catchtable/member/domain/Member.java | 48 ++++++++++++++++++- 2 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/prgrms/catchtable/common/Role.java diff --git a/src/main/java/com/prgrms/catchtable/common/Role.java b/src/main/java/com/prgrms/catchtable/common/Role.java new file mode 100644 index 00000000..b8b13051 --- /dev/null +++ b/src/main/java/com/prgrms/catchtable/common/Role.java @@ -0,0 +1,14 @@ +package com.prgrms.catchtable.common; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@RequiredArgsConstructor +public enum Role { + + MEMBER("ROLE_MEMBER"), + OWNER("ROLE_OWNER"); + + private final String role; +} diff --git a/src/main/java/com/prgrms/catchtable/member/domain/Member.java b/src/main/java/com/prgrms/catchtable/member/domain/Member.java index 5d076350..a11c9209 100644 --- a/src/main/java/com/prgrms/catchtable/member/domain/Member.java +++ b/src/main/java/com/prgrms/catchtable/member/domain/Member.java @@ -5,20 +5,26 @@ import static lombok.AccessLevel.PROTECTED; import com.prgrms.catchtable.common.BaseEntity; +import com.prgrms.catchtable.common.Role; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.Enumerated; import jakarta.persistence.GeneratedValue; import jakarta.persistence.Id; import java.time.LocalDate; +import java.util.Collection; +import java.util.Collections; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; @Getter @NoArgsConstructor(access = PROTECTED) @Entity -public class Member extends BaseEntity { +public class Member extends BaseEntity implements UserDetails { @Id @GeneratedValue(strategy = IDENTITY) @@ -38,6 +44,10 @@ public class Member extends BaseEntity { @Enumerated(STRING) private Gender gender; + @Column(name = "role") + @Enumerated(STRING) + private Role role; + @Column(name = "date_birth") private LocalDate dateBirth; @@ -52,5 +62,41 @@ public Member(String name, String email, String phoneNumber, Gender gender, Loca this.gender = gender; this.dateBirth = dateBirth; this.notification_activated = true; + this.role = Role.MEMBER; + } + + @Override + public Collection getAuthorities() { + return Collections.singletonList(new SimpleGrantedAuthority(role.getRole())); + } + + @Override + public String getPassword() { + return null; + } + + @Override + public String getUsername() { + return email; + } + + @Override + public boolean isAccountNonExpired() { + return true; + } + + @Override + public boolean isAccountNonLocked() { + return true; + } + + @Override + public boolean isCredentialsNonExpired() { + return true; + } + + @Override + public boolean isEnabled() { + return true; } } From efc32e139d8e88f0709f96690b192181901f0023 Mon Sep 17 00:00:00 2001 From: kkangh00n Date: Wed, 27 Dec 2023 01:11:04 +0900 Subject: [PATCH 13/23] =?UTF-8?q?feat=20:=20=EC=9A=94=EC=B2=AD=20=EC=8B=9C?= =?UTF-8?q?,=20JWT=20=ED=86=A0=ED=81=B0=EC=9D=84=20=EC=9D=B4=EC=9A=A9?= =?UTF-8?q?=ED=95=9C=20=EC=82=AC=EC=9A=A9=EC=9E=90=20=EC=9D=B8=EC=A6=9D=20?= =?UTF-8?q?=ED=95=84=ED=84=B0=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jwt/filter/JwtAuthenticationFilter.java | 63 +++++++++++++++++++ .../jwt/provider/JwtTokenProvider.java | 37 ++++++++++- .../repository/RefreshTokenRepository.java | 3 + .../jwt/service/JwtUserDetailsService.java | 21 +++++++ .../jwt/service/RefreshTokenService.java | 6 ++ 5 files changed, 129 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/prgrms/catchtable/jwt/filter/JwtAuthenticationFilter.java create mode 100644 src/main/java/com/prgrms/catchtable/jwt/service/JwtUserDetailsService.java diff --git a/src/main/java/com/prgrms/catchtable/jwt/filter/JwtAuthenticationFilter.java b/src/main/java/com/prgrms/catchtable/jwt/filter/JwtAuthenticationFilter.java new file mode 100644 index 00000000..52762b7a --- /dev/null +++ b/src/main/java/com/prgrms/catchtable/jwt/filter/JwtAuthenticationFilter.java @@ -0,0 +1,63 @@ +package com.prgrms.catchtable.jwt.filter; + +import com.prgrms.catchtable.jwt.domain.RefreshToken; +import com.prgrms.catchtable.jwt.provider.JwtTokenProvider; +import com.prgrms.catchtable.jwt.service.RefreshTokenService; +import com.prgrms.catchtable.jwt.token.Token; +import jakarta.servlet.FilterChain; +import jakarta.servlet.GenericFilter; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import java.io.IOException; +import lombok.RequiredArgsConstructor; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor +public class JwtAuthenticationFilter extends GenericFilter { + + private final JwtTokenProvider jwtTokenProvider; + + private final RefreshTokenService refreshTokenService; + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException { + + String accessToken = ((HttpServletRequest) request).getHeader("AccessToken"); + String refreshToken = ((HttpServletRequest) request).getHeader("RefreshToken"); + + if(accessToken!=null){ + //AccessToken 유효 + if(jwtTokenProvider.validateToken(accessToken)){ + setAuthentication(accessToken); + } + //RefreshToken 유효 + else{ + if(jwtTokenProvider.validateToken(refreshToken)){ + RefreshToken refreshTokenEntity = refreshTokenService.getRefreshTokenByToken( + refreshToken); + String email = refreshTokenEntity.getEmail(); + Token newToken = jwtTokenProvider.createToken(email); + + ((HttpServletResponse) response).setHeader("AccessToken", newToken.getAccessToken()); + setAuthentication(newToken.getAccessToken()); + } + else{ + throw new UsernameNotFoundException("Please Login again"); + } + } + } + } + + private void setAuthentication(String accessToken) { + Authentication authentication = jwtTokenProvider.getAuthentication(accessToken); + SecurityContextHolder.getContext().setAuthentication(authentication); + } +} diff --git a/src/main/java/com/prgrms/catchtable/jwt/provider/JwtTokenProvider.java b/src/main/java/com/prgrms/catchtable/jwt/provider/JwtTokenProvider.java index 3bfb4819..9d72a47c 100644 --- a/src/main/java/com/prgrms/catchtable/jwt/provider/JwtTokenProvider.java +++ b/src/main/java/com/prgrms/catchtable/jwt/provider/JwtTokenProvider.java @@ -2,12 +2,17 @@ import com.prgrms.catchtable.jwt.config.JwtConfig; +import com.prgrms.catchtable.jwt.service.JwtUserDetailsService; import com.prgrms.catchtable.jwt.token.Token; import io.jsonwebtoken.Claims; +import io.jsonwebtoken.JwtException; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; import java.util.Date; import lombok.RequiredArgsConstructor; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.userdetails.UserDetails; import org.springframework.stereotype.Component; @Component @@ -16,6 +21,8 @@ public class JwtTokenProvider { private final JwtConfig jwtConfig; + private final JwtUserDetailsService jwtUserDetailsService; + public Token createToken(String email) { Claims claims = Jwts.claims().setSubject(email); @@ -25,7 +32,6 @@ public Token createToken(String email) { String refreshToken = createRefreshToken(claims, now); return new Token(accessToken, refreshToken, email); - } private String createAccessToken(Claims claims, Date now) { @@ -51,4 +57,33 @@ private String createRefreshToken(Claims claims, Date now) { .compact(); } + public boolean validateToken(String token) { + try{ + Claims claims = Jwts.parserBuilder() + .setSigningKey(jwtConfig.getClientSecret()) + .build() + .parseClaimsJws(token) + .getBody(); + + return claims.getExpiration().after(new Date()); + } catch(JwtException je){ + return false; + } + } + + public Authentication getAuthentication(String token){ + String email = getEmail(token); + UserDetails userDetails = jwtUserDetailsService.loadUserByUsername(email); + return new UsernamePasswordAuthenticationToken(userDetails, "", userDetails.getAuthorities()); + } + + private String getEmail(String token){ + Claims claims = Jwts.parserBuilder() + .setSigningKey(jwtConfig.getClientSecret()) + .build() + .parseClaimsJws(token) + .getBody(); + + return claims.getSubject(); + } } diff --git a/src/main/java/com/prgrms/catchtable/jwt/repository/RefreshTokenRepository.java b/src/main/java/com/prgrms/catchtable/jwt/repository/RefreshTokenRepository.java index 5caaed13..688fca16 100644 --- a/src/main/java/com/prgrms/catchtable/jwt/repository/RefreshTokenRepository.java +++ b/src/main/java/com/prgrms/catchtable/jwt/repository/RefreshTokenRepository.java @@ -1,6 +1,7 @@ package com.prgrms.catchtable.jwt.repository; import com.prgrms.catchtable.jwt.domain.RefreshToken; +import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; public interface RefreshTokenRepository extends JpaRepository { @@ -8,4 +9,6 @@ public interface RefreshTokenRepository extends JpaRepository findRefreshTokenByToken(String token); } diff --git a/src/main/java/com/prgrms/catchtable/jwt/service/JwtUserDetailsService.java b/src/main/java/com/prgrms/catchtable/jwt/service/JwtUserDetailsService.java new file mode 100644 index 00000000..a259842b --- /dev/null +++ b/src/main/java/com/prgrms/catchtable/jwt/service/JwtUserDetailsService.java @@ -0,0 +1,21 @@ +package com.prgrms.catchtable.jwt.service; + +import com.prgrms.catchtable.member.repository.MemberRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class JwtUserDetailsService implements UserDetailsService { + + private final MemberRepository memberRepository; + + @Override + public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException { + return memberRepository.findMemberByEmail(email) + .orElseThrow(() -> new UsernameNotFoundException("Not Found Member")); + } +} diff --git a/src/main/java/com/prgrms/catchtable/jwt/service/RefreshTokenService.java b/src/main/java/com/prgrms/catchtable/jwt/service/RefreshTokenService.java index 7683ba73..3c072f9d 100644 --- a/src/main/java/com/prgrms/catchtable/jwt/service/RefreshTokenService.java +++ b/src/main/java/com/prgrms/catchtable/jwt/service/RefreshTokenService.java @@ -4,6 +4,7 @@ import com.prgrms.catchtable.jwt.repository.RefreshTokenRepository; import com.prgrms.catchtable.jwt.token.Token; import lombok.RequiredArgsConstructor; +import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -29,4 +30,9 @@ public void saveRefreshToken(Token totalToken){ refreshTokenRepository.save(newRefreshToken); } + @Transactional(readOnly = true) + public RefreshToken getRefreshTokenByToken(String refreshToken){ + return refreshTokenRepository.findRefreshTokenByToken(refreshToken) + .orElseThrow(() -> new UsernameNotFoundException("Not Found RefreshToken")); + } } From a97bccc0d14fa8752e0a2b5ddd2503fe67831e67 Mon Sep 17 00:00:00 2001 From: kkangh00n Date: Wed, 27 Dec 2023 11:28:42 +0900 Subject: [PATCH 14/23] =?UTF-8?q?feat=20:=20JwtAuthenticationFilter=20?= =?UTF-8?q?=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../prgrms/catchtable/security/config/SecurityConfig.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/java/com/prgrms/catchtable/security/config/SecurityConfig.java b/src/main/java/com/prgrms/catchtable/security/config/SecurityConfig.java index 6de948cf..f6a991de 100644 --- a/src/main/java/com/prgrms/catchtable/security/config/SecurityConfig.java +++ b/src/main/java/com/prgrms/catchtable/security/config/SecurityConfig.java @@ -1,5 +1,6 @@ package com.prgrms.catchtable.security.config; +import com.prgrms.catchtable.jwt.filter.JwtAuthenticationFilter; import com.prgrms.catchtable.security.service.CustomOAuth2SuccessHandler; import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Bean; @@ -7,6 +8,7 @@ import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestRedirectFilter; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.util.matcher.AntPathRequestMatcher; import org.springframework.stereotype.Component; @@ -18,6 +20,8 @@ public class SecurityConfig { private final CustomOAuth2SuccessHandler successHandler; + private final JwtAuthenticationFilter jwtAuthenticationFilter; + @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { @@ -31,6 +35,8 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti ) .oauth2Login(oauth2Login -> oauth2Login.successHandler(successHandler)); + http.addFilterBefore(jwtAuthenticationFilter, OAuth2AuthorizationRequestRedirectFilter.class); + return http.build(); } From 63b6a888d0884a94d8337d2f866b2d70b45bf3c4 Mon Sep 17 00:00:00 2001 From: kkangh00n Date: Wed, 27 Dec 2023 11:28:51 +0900 Subject: [PATCH 15/23] =?UTF-8?q?fix=20:=20=EB=88=84=EB=9D=BD=20=EB=A9=94?= =?UTF-8?q?=EC=84=9C=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../prgrms/catchtable/jwt/filter/JwtAuthenticationFilter.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/prgrms/catchtable/jwt/filter/JwtAuthenticationFilter.java b/src/main/java/com/prgrms/catchtable/jwt/filter/JwtAuthenticationFilter.java index 52762b7a..3ccbf8ed 100644 --- a/src/main/java/com/prgrms/catchtable/jwt/filter/JwtAuthenticationFilter.java +++ b/src/main/java/com/prgrms/catchtable/jwt/filter/JwtAuthenticationFilter.java @@ -54,6 +54,7 @@ public void doFilter(ServletRequest request, ServletResponse response, FilterCha } } } + chain.doFilter(request, response); } private void setAuthentication(String accessToken) { From d2e967fa706f65be359bd50f5685f39edddd60f4 Mon Sep 17 00:00:00 2001 From: kkangh00n Date: Wed, 27 Dec 2023 14:36:20 +0900 Subject: [PATCH 16/23] =?UTF-8?q?style=20:=20=EC=9D=B8=EB=8D=B4=ED=8A=B8?= =?UTF-8?q?=20=EC=BB=A8=EB=B2=A4=EC=85=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jwt/filter/JwtAuthenticationFilter.java | 14 +++++++------- .../catchtable/jwt/provider/JwtTokenProvider.java | 11 ++++++----- .../jwt/service/RefreshTokenService.java | 6 +++--- .../prgrms/catchtable/member/domain/Member.java | 3 ++- .../catchtable/member/service/MemberService.java | 2 +- .../catchtable/security/config/SecurityConfig.java | 3 ++- 6 files changed, 21 insertions(+), 18 deletions(-) diff --git a/src/main/java/com/prgrms/catchtable/jwt/filter/JwtAuthenticationFilter.java b/src/main/java/com/prgrms/catchtable/jwt/filter/JwtAuthenticationFilter.java index 3ccbf8ed..f7651cb6 100644 --- a/src/main/java/com/prgrms/catchtable/jwt/filter/JwtAuthenticationFilter.java +++ b/src/main/java/com/prgrms/catchtable/jwt/filter/JwtAuthenticationFilter.java @@ -33,23 +33,23 @@ public void doFilter(ServletRequest request, ServletResponse response, FilterCha String accessToken = ((HttpServletRequest) request).getHeader("AccessToken"); String refreshToken = ((HttpServletRequest) request).getHeader("RefreshToken"); - if(accessToken!=null){ + if (accessToken != null) { //AccessToken 유효 - if(jwtTokenProvider.validateToken(accessToken)){ + if (jwtTokenProvider.validateToken(accessToken)) { setAuthentication(accessToken); } //RefreshToken 유효 - else{ - if(jwtTokenProvider.validateToken(refreshToken)){ + else { + if (jwtTokenProvider.validateToken(refreshToken)) { RefreshToken refreshTokenEntity = refreshTokenService.getRefreshTokenByToken( refreshToken); String email = refreshTokenEntity.getEmail(); Token newToken = jwtTokenProvider.createToken(email); - ((HttpServletResponse) response).setHeader("AccessToken", newToken.getAccessToken()); + ((HttpServletResponse) response).setHeader("AccessToken", + newToken.getAccessToken()); setAuthentication(newToken.getAccessToken()); - } - else{ + } else { throw new UsernameNotFoundException("Please Login again"); } } diff --git a/src/main/java/com/prgrms/catchtable/jwt/provider/JwtTokenProvider.java b/src/main/java/com/prgrms/catchtable/jwt/provider/JwtTokenProvider.java index 9d72a47c..9bc8f529 100644 --- a/src/main/java/com/prgrms/catchtable/jwt/provider/JwtTokenProvider.java +++ b/src/main/java/com/prgrms/catchtable/jwt/provider/JwtTokenProvider.java @@ -58,7 +58,7 @@ private String createRefreshToken(Claims claims, Date now) { } public boolean validateToken(String token) { - try{ + try { Claims claims = Jwts.parserBuilder() .setSigningKey(jwtConfig.getClientSecret()) .build() @@ -66,18 +66,19 @@ public boolean validateToken(String token) { .getBody(); return claims.getExpiration().after(new Date()); - } catch(JwtException je){ + } catch (JwtException je) { return false; } } - public Authentication getAuthentication(String token){ + public Authentication getAuthentication(String token) { String email = getEmail(token); UserDetails userDetails = jwtUserDetailsService.loadUserByUsername(email); - return new UsernamePasswordAuthenticationToken(userDetails, "", userDetails.getAuthorities()); + return new UsernamePasswordAuthenticationToken(userDetails, "", + userDetails.getAuthorities()); } - private String getEmail(String token){ + private String getEmail(String token) { Claims claims = Jwts.parserBuilder() .setSigningKey(jwtConfig.getClientSecret()) .build() diff --git a/src/main/java/com/prgrms/catchtable/jwt/service/RefreshTokenService.java b/src/main/java/com/prgrms/catchtable/jwt/service/RefreshTokenService.java index 3c072f9d..be10c362 100644 --- a/src/main/java/com/prgrms/catchtable/jwt/service/RefreshTokenService.java +++ b/src/main/java/com/prgrms/catchtable/jwt/service/RefreshTokenService.java @@ -15,10 +15,10 @@ public class RefreshTokenService { private final RefreshTokenRepository refreshTokenRepository; @Transactional - public void saveRefreshToken(Token totalToken){ + public void saveRefreshToken(Token totalToken) { String email = totalToken.getEmail(); - if(refreshTokenRepository.existsRefreshTokenByEmail(email)){ + if (refreshTokenRepository.existsRefreshTokenByEmail(email)) { refreshTokenRepository.deleteRefreshTokenByEmail(email); } @@ -31,7 +31,7 @@ public void saveRefreshToken(Token totalToken){ } @Transactional(readOnly = true) - public RefreshToken getRefreshTokenByToken(String refreshToken){ + public RefreshToken getRefreshTokenByToken(String refreshToken) { return refreshTokenRepository.findRefreshTokenByToken(refreshToken) .orElseThrow(() -> new UsernameNotFoundException("Not Found RefreshToken")); } diff --git a/src/main/java/com/prgrms/catchtable/member/domain/Member.java b/src/main/java/com/prgrms/catchtable/member/domain/Member.java index a11c9209..08a72ec0 100644 --- a/src/main/java/com/prgrms/catchtable/member/domain/Member.java +++ b/src/main/java/com/prgrms/catchtable/member/domain/Member.java @@ -55,7 +55,8 @@ public class Member extends BaseEntity implements UserDetails { private boolean notification_activated; @Builder - public Member(String name, String email, String phoneNumber, Gender gender, LocalDate dateBirth) { + public Member(String name, String email, String phoneNumber, Gender gender, + LocalDate dateBirth) { this.name = name; this.email = email; this.phoneNumber = phoneNumber; diff --git a/src/main/java/com/prgrms/catchtable/member/service/MemberService.java b/src/main/java/com/prgrms/catchtable/member/service/MemberService.java index 7ce7aed7..82d85412 100644 --- a/src/main/java/com/prgrms/catchtable/member/service/MemberService.java +++ b/src/main/java/com/prgrms/catchtable/member/service/MemberService.java @@ -35,7 +35,7 @@ public Token oauthLogin(OAuthAttribute attributes) { return createTotalToken(email); } - private Token createTotalToken(String email){ + private Token createTotalToken(String email) { Token totalToken = jwtTokenProvider.createToken(email); refreshTokenService.saveRefreshToken(totalToken); return totalToken; diff --git a/src/main/java/com/prgrms/catchtable/security/config/SecurityConfig.java b/src/main/java/com/prgrms/catchtable/security/config/SecurityConfig.java index f6a991de..8b9edb01 100644 --- a/src/main/java/com/prgrms/catchtable/security/config/SecurityConfig.java +++ b/src/main/java/com/prgrms/catchtable/security/config/SecurityConfig.java @@ -35,7 +35,8 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti ) .oauth2Login(oauth2Login -> oauth2Login.successHandler(successHandler)); - http.addFilterBefore(jwtAuthenticationFilter, OAuth2AuthorizationRequestRedirectFilter.class); + http.addFilterBefore(jwtAuthenticationFilter, + OAuth2AuthorizationRequestRedirectFilter.class); return http.build(); } From 86ea0178a7adb7410a71142d4b65d9cf23a16741 Mon Sep 17 00:00:00 2001 From: kkangh00n Date: Mon, 1 Jan 2024 18:01:52 +0900 Subject: [PATCH 17/23] =?UTF-8?q?refactor=20:=20=EB=88=84=EB=9D=BD=20?= =?UTF-8?q?=EC=A0=91=EA=B7=BC=20=EC=A0=9C=EC=96=B4=EC=9E=90=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../catchtable/security/dto/OAuthAttribute.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/prgrms/catchtable/security/dto/OAuthAttribute.java b/src/main/java/com/prgrms/catchtable/security/dto/OAuthAttribute.java index 8c0d689c..87dc486e 100644 --- a/src/main/java/com/prgrms/catchtable/security/dto/OAuthAttribute.java +++ b/src/main/java/com/prgrms/catchtable/security/dto/OAuthAttribute.java @@ -8,17 +8,17 @@ @Getter public class OAuthAttribute { - String name; + private final String name; - String email; + private final String email; - String phoneNumber; + private final String phoneNumber; - String birthYear; + private final String birthYear; - String birthDay; + private final String birthDay; - String gender; + private final String gender; @Builder public OAuthAttribute(String name, String email, String phoneNumber, String birthYear, From e177ee51ba1db480bcbe8c2a02d92e68c4ab1bc7 Mon Sep 17 00:00:00 2001 From: kkangh00n Date: Mon, 1 Jan 2024 18:09:51 +0900 Subject: [PATCH 18/23] chore : conflict resolve --- build.gradle | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 86b3657b..73a589d7 100644 --- a/build.gradle +++ b/build.gradle @@ -49,6 +49,9 @@ dependencies { asciidoctorExt 'org.springframework.restdocs:spring-restdocs-asciidoctor' testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc' + testCompileOnly 'org.projectlombok:lombok' + testAnnotationProcessor 'org.projectlombok:lombok' + //OAuth2.0 Client implementation 'org.springframework.boot:spring-boot-starter-oauth2-client' @@ -56,7 +59,6 @@ dependencies { implementation 'io.jsonwebtoken:jjwt-api:0.11.5' runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5' runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.5' - } tasks.named('test') { From 8db399fbb3ab11db25244c3916ad79e82e58e546 Mon Sep 17 00:00:00 2001 From: kkangh00n Date: Mon, 1 Jan 2024 18:12:00 +0900 Subject: [PATCH 19/23] chore : conflict resolve --- build.gradle | 8 -------- 1 file changed, 8 deletions(-) diff --git a/build.gradle b/build.gradle index 73a589d7..361994f5 100644 --- a/build.gradle +++ b/build.gradle @@ -51,14 +51,6 @@ dependencies { testCompileOnly 'org.projectlombok:lombok' testAnnotationProcessor 'org.projectlombok:lombok' - - //OAuth2.0 Client - implementation 'org.springframework.boot:spring-boot-starter-oauth2-client' - - //JWT - implementation 'io.jsonwebtoken:jjwt-api:0.11.5' - runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5' - runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.5' } tasks.named('test') { From 4b3136b0deea46182d8ac0e50d438ec608561324 Mon Sep 17 00:00:00 2001 From: kkangh00n Date: Mon, 1 Jan 2024 18:13:18 +0900 Subject: [PATCH 20/23] chore : conflict resolve --- build.gradle | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/build.gradle b/build.gradle index 361994f5..73a589d7 100644 --- a/build.gradle +++ b/build.gradle @@ -51,6 +51,14 @@ dependencies { testCompileOnly 'org.projectlombok:lombok' testAnnotationProcessor 'org.projectlombok:lombok' + + //OAuth2.0 Client + implementation 'org.springframework.boot:spring-boot-starter-oauth2-client' + + //JWT + implementation 'io.jsonwebtoken:jjwt-api:0.11.5' + runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5' + runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.5' } tasks.named('test') { From c00daa5cd6c7de3206f659efd81b5a43582c2eaf Mon Sep 17 00:00:00 2001 From: kkangh00n Date: Mon, 1 Jan 2024 18:21:11 +0900 Subject: [PATCH 21/23] chore : conflict resolve --- build.gradle | 8 -------- 1 file changed, 8 deletions(-) diff --git a/build.gradle b/build.gradle index 73a589d7..361994f5 100644 --- a/build.gradle +++ b/build.gradle @@ -51,14 +51,6 @@ dependencies { testCompileOnly 'org.projectlombok:lombok' testAnnotationProcessor 'org.projectlombok:lombok' - - //OAuth2.0 Client - implementation 'org.springframework.boot:spring-boot-starter-oauth2-client' - - //JWT - implementation 'io.jsonwebtoken:jjwt-api:0.11.5' - runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5' - runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.5' } tasks.named('test') { From 0495100161770774dee74db7c96117da283d8274 Mon Sep 17 00:00:00 2001 From: kkangh00n Date: Mon, 1 Jan 2024 18:31:44 +0900 Subject: [PATCH 22/23] chore : conflict resolve --- build.gradle | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/build.gradle b/build.gradle index 361994f5..63572141 100644 --- a/build.gradle +++ b/build.gradle @@ -49,6 +49,14 @@ dependencies { asciidoctorExt 'org.springframework.restdocs:spring-restdocs-asciidoctor' testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc' + //OAuth2.0 Client + implementation 'org.springframework.boot:spring-boot-starter-oauth2-client' + + //JWT + implementation 'io.jsonwebtoken:jjwt-api:0.11.5' + runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5' + runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.5' + testCompileOnly 'org.projectlombok:lombok' testAnnotationProcessor 'org.projectlombok:lombok' } From f7799fe552a640438b136a9ab3a0550afe4bef68 Mon Sep 17 00:00:00 2001 From: kkangh00n Date: Mon, 1 Jan 2024 18:34:47 +0900 Subject: [PATCH 23/23] chore : conflict resolve --- build.gradle | 8 -------- 1 file changed, 8 deletions(-) diff --git a/build.gradle b/build.gradle index 63572141..361994f5 100644 --- a/build.gradle +++ b/build.gradle @@ -49,14 +49,6 @@ dependencies { asciidoctorExt 'org.springframework.restdocs:spring-restdocs-asciidoctor' testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc' - //OAuth2.0 Client - implementation 'org.springframework.boot:spring-boot-starter-oauth2-client' - - //JWT - implementation 'io.jsonwebtoken:jjwt-api:0.11.5' - runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5' - runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.5' - testCompileOnly 'org.projectlombok:lombok' testAnnotationProcessor 'org.projectlombok:lombok' }